from:http://blog.csdn.net/signmem/article/details/17379427

特色
MySQL/Galera 是一種多主同步集群,但只限于使用 MySQL/InnoDB 引擎,并具有下面特點
同步復制
多個主服務器的拓撲結構
可以在任意節點上進行讀寫
自動控制成員,自動刪除故障節點
自動加入節點
真正給予行級別的并發復制
調度客戶連接

優勢
參考下面基于 DBMS 集群的解決方法
不存在從服務器角色
不存在事務丟失
讀寫操作可根據需要進行隨意擴展
更少的閂操作


知識點
MySQL/Galera 集群使用 Galera 庫執行復制,對應 Galera 復制接口,我們需要MySQL 服務器支持 wsrep API 接口
http://www.codership.com/products/mysql-write-set-replication-project


是否可以使用 MySQL 而不使用 mariadb?
不可以,因為 mysql 中沒有支持 wsrep_ 數據復制的參數,當然代碼級別上也具有很大差別

 

工作原理


mariadb 可以看做是常見的數據庫,負責連接應用(web, API 等)
單純的 mariadb  無法實現多個主服務器數據同步
多臺數據庫中數據同步由 wsrep 接口實現

最終目標,實現多個 MySQL 同時讀寫 

wsrep API
wsrep API 是一種數據庫插件接口,比較類似一種應用程序,主要針對寫復制
該程序主要用于定義應用程序如何調用復制庫實現回寫
wsrep API 由支持改庫的應用程序動態裝載


全局事務ID(GTID)
wsrep API 描述下面復制模型,一個應用程序,如數據庫當前的一個對象,當前被客戶端修改,對象改變導致事務產生一系列的原子性改變, 在集群中所有的節點都具備相同的對象,并由同步復制應用都各自節點,按照相同的順序產生相同變化從而實現數據同步


到最后,wsrep API 將會分配一個全局事務ID 該 ID 具有下面功能
標識對象的改變
標識對象自身 ID 最后狀態(正常情況下,ID 是連續不中斷的)

GTID 包含
一個 UUID 作為對象標識及經歷改變的序號,序號會發生連續的改變
GTID 允許比較應用程序狀態,建立對象改變的順序,決定對象的變化是否需要更新 GTID
通常 GTID 會卑記錄成下面格式
45eec521-2f34-11e0-0800-2a36050b826b:94530586304

 

言歸正傳,我們需要編譯 mariadb-mysql  及  galera 插件

galera/mysql 編譯步驟

https://downloads.mariadb.org/interstitial/mariadb-galera-5.5.33a/kvm-tarbake-jaunty-x86/mariadb-galera-5.5.33a.tar.gz/from/http://mirrors.scie.in/mariadb

yum install -y cmake

tar xf mariadb-galera-5.5.33a.tar.gz
cd mariadb-5.5.33a/
cmake -LAH

參考 CMakeCache.txt 文件中的配置信息

  1. cmake -DINSTALL_MYSQLDATADIR:STRING=/mdb -DINSTALL_UNIX_ADDRDIR:STRING=/var/run/mysqld/mysql5.socket  
  2. make  
  3. make install  


默認情況下, mariadb  安裝在  /usr/local/mysql

 

galera 編譯

https://launchpad.net/galera/2.x/23.2.7/+download/galera-23.2.7-src.tar.gz

添加數據源

  1. baseurl=http://mirror.neu.edu.cn/fedora/epel//6Server/x86_64/  

添加下面軟件包

  1. yum erase -y mysql.x86_64 mysql-devel.x86_64 mysql-libs.x86_64    
  2. yum install -y boost-devel.x86_64 libodb-boost-devel.x86_64  bzr scons  


解壓 galera-23.2.7-src.tar.gz 并進行編譯

  1. cd /usr/src  
  2. tar xf galera-23.2.7-src.tar.gz  
  3. cd galera-23.2.7-src  
  4. scons  


注: scons 為編譯命令
 

編譯后能生成 libgalera_smm.so

復制編譯好的庫至下面位置 /usr/local/galera/lib/libgalera_smm.so

  1. mkdir /usr/local/galera/lib -p  
  2. cp /usr/src/galera-23.2.7-src/libgalera_smm.so /usr/local/galera/lib/libgalera_smm.so  


復制 啟動腳本 /usr/src/galera-23.2.7-src/scripts/mysql/mysql-galera 到 /usr/local

  1. cp  /usr/src/galera-23.2.7-src/scripts/mysql/mysql-galera /usr/local  


創建 /usr/local/mysql/etc/my.cnf

  1. [mysqld]  
  2. basedir=/usr/local/mysql  
  3. big-tables  
  4. bind-address=0.0.0.0  
  5. character-set-server=utf8  
  6. datadir=/mdb  
  7. log-error=/var/log/mysqld/mysql5-error.log  
  8. socket=/var/run/mysqld/mysql5.socket  
  9. pid-file=/var/run/mysqld/mysql5.pid  
  10. port=3306  
  11. user=mysql  
  12.   
  13. binlog_format = ROW  
  14. binlog_cache_size = 1M  
  15. character_set_server = utf8  
  16. collation_server = utf8_general_ci  
  17.   
  18. default-storage-engine = InnoDB  
  19.   
  20. expire_logs_days = 10  
  21.   
  22. innodb_buffer_pool_size = 300M  
  23. innodb_thread_concurrency = 16  
  24. innodb_log_buffer_size = 8M  
  25.   
  26. innodb_doublewrite = 1  
  27. innodb_file_per_table = 1  
  28. innodb_flush_log_at_trx_commit = 2  
  29.   
  30. server-id = 1  
  31. max_connections = 1000  
  32.   
  33. net_buffer_length = 8K  
  34. open-files-limit = 65535  
  35.   
  36. wsrep_cluster_address = 'gcomm://192.168.200.163,192.168.200.171,172.18.8.49,172.18.8.50'  
  37. wsrep_provider = /usr/local/galera/lib/libgalera_smm.so  
  38. wsrep_retry_autocommit = 0  
  39. wsrep_sst_method = rsync  
  40. wsrep_provider_options="gcache.size=256m; gcache.page_size=256m"  
  41. wsrep_slave_threads=16  
  42.   
  43. wsrep_cluster_name='my_cluster'  
  44. wsrep_node_name='db5'  
  45.   
  46. wsrep_sst_auth=tt:tt123  

 


maridb 啟動測試

初始化數據庫

  1. mkdir /mdb  
  2. cd /usr/local/mysql  
  3. ./scripts/install_mysql_db --datadir=/mdb  


啟動腳本 /etc/rc.d/init.d/mysql5 確保文件可執行權限

  1. #!/bin/sh  
  2. # chkconfig: 2345 64 36  
  3. # description: A very fast and reliable SQL database engine.  
  4. <p>basedir=/usr/local/mysql  
  5. datadir=/mdb</p><p># Default value, in seconds, afterwhich the script should timeout waiting  
  6. # for server start.  
  7. # Value here is overriden by value in my.cnf.  
  8. # 0 means don't wait at all  
  9. # Negative numbers mean to wait indefinitely  
  10. service_startup_timeout=900  
  11. startup_sleep=1</p><p># Lock directory for RedHat / SuSE.  
  12. lockdir='/var/lock/subsys'  
  13. lock_file_path="$lockdir/mysql"</p><p># The following variables are only set for letting mysql.server find things.</p><p># Set some defaults  
  14. mysqld_pid_file_path=/var/run/mysqld/mysql5.pid  
  15. if test -z "$basedir"  
  16. then  
  17.   basedir=/usr/local/mysql  
  18.   bindir=/usr/local/mysql/bin  
  19.   if test -z "$datadir"  
  20.   then  
  21.     datadir=/usr/local/mysql/data  
  22.   fi  
  23.   sbindir=/usr/local/mysql/bin  
  24.   libexecdir=/usr/local/mysql/bin  
  25. </p><p>else  
  26.   bindir="$basedir/bin"  
  27.   if test -z "$datadir"  
  28.   then  
  29.     datadir="$basedir/data"  
  30.   fi  
  31.   sbindir="$basedir/sbin"  
  32.   if test -f "$basedir/bin/mysqld"  
  33.   then  
  34.     libexecdir="$basedir/bin"  
  35.   else  
  36.     libexecdir="$basedir/libexec"  
  37.   fi  
  38. fi</p><p># datadir_set is used to determine if datadir was set (and so should be  
  39. # *not* set inside of the --basedir= handler.)  
  40. datadir_set=</p><p>#  
  41. # Use LSB init script functions for printing messages, if possible  
  42. #  
  43. lsb_functions="/lib/lsb/init-functions"  
  44. if test -f $lsb_functions ; then  
  45.   . $lsb_functions  
  46. else  
  47.   log_success_msg()  
  48.   {  
  49.     echo " SUCCESS! $@"  
  50.   }  
  51.   log_failure_msg()  
  52.   {  
  53.     echo " ERROR! $@"  
  54.   }  
  55. fi</p><p>PATH="/sbin:/usr/sbin:/bin:/usr/bin:$basedir/bin"  
  56. </p><p>export PATH</p><p>mode=$1    # start or stop</p><p>[ $# -ge 1 ] && shift</p><p>  
  57. other_args="$*"   # uncommon, but needed when called from an RPM upgrade action  
  58.            # Expected: "--skip-networking --skip-grant-tables"  
  59.            # They are not checked here, intentionally, as it is the resposibility  
  60.            # of the "spec" file author to give correct arguments only.</p><p>case `echo "testing\c"`,`echo -n testing` in  
  61.     *c*,-n*) echo_n=   echo_c=     ;;  
  62.     *c*,*)   echo_n=-n echo_c=     ;;  
  63.     *)       echo_n=   echo_c='\c' ;;  
  64. esac</p><p>parse_server_arguments() {  
  65.   for arg do  
  66.     case "$arg" in  
  67.       --basedir=*)  basedir=`echo "$arg" | sed -e 's/^[^=]*=//'`  
  68.                     bindir="$basedir/bin"  
  69.                     if test -z "$datadir_set"; then  
  70.                       datadir="$basedir/data"  
  71.                     fi  
  72.                     sbindir="$basedir/sbin"  
  73.                     if test -f "$basedir/bin/mysqld"  
  74.                     then  
  75.                       libexecdir="$basedir/bin"  
  76.                     else  
  77.                       libexecdir="$basedir/libexec"  
  78.                     fi  
  79.                     libexecdir="$basedir/libexec"  
  80.         ;;  
  81.       --datadir=*)  datadir=`echo "$arg" | sed -e 's/^[^=]*=//'`  
  82.                     datadir_set=1  
  83. </p><p>        ;;  
  84.       --pid-file=*) mysqld_pid_file_path=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;  
  85.       --service-startup-timeout=*) service_startup_timeout=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;  
  86.     esac  
  87.   done  
  88. }</p><p>wait_for_pid () {  
  89.   verb="$1"           # created | removed  
  90.   pid="$2"            # process ID of the program operating on the pid-file  
  91.   pid_file_path="$3" # path to the PID file.</p><p>  sst_progress_file=$datadir/sst_in_progress  
  92.   i=0  
  93.   avoid_race_condition="by checking again"</p><p>  while test $i -ne $service_startup_timeout ; do</p><p>    case "$verb" in  
  94.       'created')  
  95.         # wait for a PID-file to pop into existence.  
  96.         test -s "$pid_file_path" && i='' && break  
  97.         ;;  
  98.       'removed')  
  99.         # wait for this PID-file to disappear  
  100.         test ! -s "$pid_file_path" && i='' && break  
  101.         ;;  
  102.       *)  
  103.         echo "wait_for_pid () usage: wait_for_pid created|removed pid pid_file_path"  
  104.         exit 1  
  105.         ;;  
  106.     esac</p><p>    # if server isn't running, then pid-file will never be updated  
  107.     if test -n "$pid"; then  
  108.       if kill -0 "$pid" 2>/dev/null; then  
  109.         :  # the server still runs  
  110. </p><p>      else  
  111.         # The server may have exited between the last pid-file check and now.  
  112.         if test -n "$avoid_race_condition"; then  
  113.           avoid_race_condition=""  
  114.           continue  # Check again.  
  115.         fi</p><p>        # there's nothing that will affect the file.  
  116.         log_failure_msg "The server quit without updating PID file ($pid_file_path)."  
  117.         return 1  # not waiting any more.  
  118.       fi  
  119.     fi</p><p>    if test -e $sst_progress_file && [ $startup_sleep -ne 100 ];then  
  120.         echo $echo_n "SST in progress, setting sleep higher"  
  121.         startup_sleep=100  
  122.     fi</p><p>    echo $echo_n ".$echo_c"  
  123.     i=`expr $i + 1`  
  124.     sleep $startup_sleep</p><p>  done</p><p>  if test -z "$i" ; then  
  125.     log_success_msg  
  126.     return 0  
  127.   else  
  128.     log_failure_msg  
  129.     return 1  
  130.   fi  
  131. }</p><p># Get arguments from the my.cnf file,  
  132. # the only group, which is read from now on is [mysqld]  
  133. if test -x ./bin/my_print_defaults  
  134. then  
  135. </p><p>  print_defaults="./bin/my_print_defaults"  
  136. elif test -x $bindir/my_print_defaults  
  137. then  
  138.   print_defaults="$bindir/my_print_defaults"  
  139. elif test -x $bindir/mysql_print_defaults  
  140. then  
  141.   print_defaults="$bindir/mysql_print_defaults"  
  142. else  
  143.   # Try to find basedir in /etc/my.cnf  
  144.   conf=/usr/local/mysql/etc/my.cnf  
  145.   print_defaults=  
  146.   if test -r $conf  
  147.   then  
  148.     subpat='^[^=]*basedir[^=]*=\(.*\)$'  
  149.     dirs=`sed -e "/$subpat/!d" -e 's//\1/' $conf`  
  150.     for d in $dirs  
  151.     do  
  152.       d=`echo $d | sed -e 's/[  ]//g'`  
  153.       if test -x "$d/bin/my_print_defaults"  
  154.       then  
  155.         print_defaults="$d/bin/my_print_defaults"  
  156.         break  
  157.       fi  
  158.       if test -x "$d/bin/mysql_print_defaults"  
  159.       then  
  160.         print_defaults="$d/bin/mysql_print_defaults"  
  161.         break  
  162.       fi  
  163.     done  
  164.   fi</p><p>  # Hope it's in the PATH ... but I doubt it  
  165.   test -z "$print_defaults" && print_defaults="my_print_defaults"  
  166. fi</p><p>#  
  167. # Read defaults file from 'basedir'.   If there is no defaults file there  
  168. </p><p># check if it's in the old (depricated) place (datadir) and read it from there  
  169. #</p><p>extra_args=""  
  170. if test -r "$basedir/my.cnf"  
  171. then  
  172.   extra_args="-e $basedir/my.cnf"  
  173. else  
  174.   if test -r "$datadir/my.cnf"  
  175.   then  
  176.     extra_args="-e $datadir/my.cnf"  
  177.   fi  
  178. fi</p><p>parse_server_arguments `$print_defaults $extra_args mysqld server mysql_server mysql.server`</p><p>#  
  179. # Set pid file if not given  
  180. #  
  181. if test -z "$mysqld_pid_file_path"  
  182. then  
  183.   mysqld_pid_file_path=$datadir/`hostname`.pid  
  184. else  
  185.   case "$mysqld_pid_file_path" in  
  186.     /* ) ;;  
  187.     * )  mysqld_pid_file_path="$datadir/$mysqld_pid_file_path" ;;  
  188.   esac  
  189. fi</p><p>case "$mode" in  
  190.   'start')  
  191.     # Start daemon</p><p>    # Safeguard (relative paths, core dumps..)  
  192.     cd $basedir</p><p>    echo $echo_n "Starting MySQL"  
  193. </p><p>    if test -x $bindir/mysqld_safe  
  194.     then  
  195.       # Give extra arguments to mysqld with the my.cnf file. This script  
  196.       # may be overwritten at next upgrade.  
  197.       $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null 2>&1 &  
  198.       wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$?</p><p>      # Make lock for RedHat / SuSE  
  199.       if test -w "$lockdir"  
  200.       then  
  201.         touch "$lock_file_path"  
  202.       fi</p><p>      exit $return_value  
  203.     else  
  204.       log_failure_msg "Couldn't find MySQL server ($bindir/mysqld_safe)"  
  205.     fi  
  206.     ;;</p><p>  'stop')  
  207.     # Stop daemon. We use a signal here to avoid having to know the  
  208.     # root password.</p><p>    if test -s "$mysqld_pid_file_path"  
  209.     then  
  210.       mysqld_pid=`cat "$mysqld_pid_file_path"`</p><p>      if (kill -0 $mysqld_pid 2>/dev/null)  
  211.       then  
  212.         echo $echo_n "Shutting down MySQL"  
  213.         kill $mysqld_pid  
  214.         # mysqld should remove the pid file when it exits, so wait for it.  
  215.         wait_for_pid removed "$mysqld_pid" "$mysqld_pid_file_path"; return_value=$?  
  216.       else  
  217.         log_failure_msg "MySQL server process #$mysqld_pid is not running!"  
  218.         rm "$mysqld_pid_file_path"  
  219.       fi  
  220. </p><p>      # Delete lock for RedHat / SuSE  
  221.       if test -f "$lock_file_path"  
  222.       then  
  223.         rm -f "$lock_file_path"  
  224.       fi  
  225.       exit $return_value  
  226.     else  
  227.       log_failure_msg "MySQL server PID file could not be found!"  
  228.     fi  
  229.     ;;</p><p>  'restart')  
  230.     # Stop the service and regardless of whether it was  
  231.     # running or not, start it again.  
  232.     if $0 stop  $other_args; then  
  233.       $0 start $other_args  
  234.     else  
  235.       log_failure_msg "Failed to stop running server, so refusing to try to start."  
  236.       exit 1  
  237.     fi  
  238.     ;;</p><p>  'reload'|'force-reload')  
  239.     if test -s "$mysqld_pid_file_path" ; then  
  240.       read mysqld_pid <  "$mysqld_pid_file_path"  
  241.       kill -HUP $mysqld_pid && log_success_msg "Reloading service MySQL"  
  242.       touch "$mysqld_pid_file_path"  
  243.     else  
  244.       log_failure_msg "MySQL PID file could not be found!"  
  245.       exit 1  
  246.     fi  
  247.     ;;  
  248.   'status')  
  249.     # First, check to see if pid file exists  
  250.     if test -s "$mysqld_pid_file_path" ; then  
  251.       read mysqld_pid < "$mysqld_pid_file_path"  
  252. </p><p>      if kill -0 $mysqld_pid 2>/dev/null ; then  
  253.         log_success_msg "MySQL running ($mysqld_pid)"  
  254.         exit 0  
  255.       else  
  256.         log_failure_msg "MySQL is not running, but PID file exists"  
  257.         exit 1  
  258.       fi  
  259.     else  
  260.       # Try to find appropriate mysqld process  
  261.       mysqld_pid=`pidof $libexecdir/mysqld`</p><p>      # test if multiple pids exist  
  262.       pid_count=`echo $mysqld_pid | wc -w`  
  263.       if test $pid_count -gt 1 ; then  
  264.         log_failure_msg "Multiple MySQL running but PID file could not be found ($mysqld_pid)"  
  265.         exit 5  
  266.       elif test -z $mysqld_pid ; then  
  267.         if test -f "$lock_file_path" ; then  
  268.           log_failure_msg "MySQL is not running, but lock file ($lock_file_path) exists"  
  269.           exit 2  
  270.         fi  
  271.         log_failure_msg "MySQL is not running"  
  272.         exit 3  
  273.       else  
  274.         log_failure_msg "MySQL is running but PID file could not be found"  
  275.         exit 4  
  276.       fi  
  277.     fi  
  278.     ;;  
  279.   'configtest')  
  280.     # Safeguard (relative paths, core dumps..)  
  281.     cd $basedir  
  282.     echo $echo_n "Testing MySQL configuration syntax"  
  283.     daemon=$bindir/mysqld  
  284.     if test -x $libexecdir/mysqld  
  285.     then  
  286.       daemon=$libexecdir/mysqld  
  287.     elif test -x $sbindir/mysqld  
  288.     then  
  289.       daemon=$sbindir/mysqld  
  290.     elif test -x `which mysqld`  
  291.     then  
  292.       daemon=`which mysqld`  
  293.     else  
  294.       log_failure_msg "Unable to locate the mysqld binary!"  
  295.       exit 1  
  296.     fi  
  297.     help_out=`$daemon --help 2>&1`; r=$?  
  298.     if test "$r" != 0 ; then  
  299.       log_failure_msg "$help_out"  
  300.       log_failure_msg "There are syntax errors in the server configuration. Please fix them!"  
  301.     else  
  302.       log_success_msg "Syntax OK"  
  303.     fi  
  304.     exit $r  
  305.     ;;  
  306.   'bootstrap')  
  307.       # Bootstrap the cluster, start the first node  
  308.       # that initiate the cluster  
  309.       echo $echo_n "Bootstrapping the cluster"  
  310.       $0 start $other_args --wsrep-new-cluster  
  311.       ;;  
  312.   *)  
  313.       # usage  
  314.       basename=`basename "$0"`  
  315.       echo "Usage: $basename  {start|stop|restart|reload|force-reload|status|configtest|bootstrap}  [ MySQL server options ]"  
  316.       exit 1  
  317.     ;;  
  318. esac</p><p>exit 0  
  319. </p>  

 

啟動每一臺數據庫

  1. service mysql5 start  


在每臺數據庫中建立下面用戶, 用于 sst 認證 (以 root 登入 mysql 數據庫后執行下面的 SQL 語句

  1. GRANT USAGE ON *.* to tt@'%' IDENTIFIED BY 'tt123';  
  2. GRANT ALL PRIVILEGES on *.* to tt@'%';  
  3. GRANT USAGE ON *.* to tt@'localhost' IDENTIFIED BY 'tt123';  
  4. GRANT ALL PRIVILEGES on *.* to tt@'localhost';  
  5. flush privileges;  


關閉所有數據庫, 集群啟動前, 不需要啟動任何一臺的數據庫

  1. service mysql5 stop  

 
創建并加入集群

集群中第一個節點啟動 (192.168.200.163)
創建軟鏈接,并啟動集群,集群啟動過程中會自動啟動 mariadb

  1. ln -s /usr/local/mysql/bin/ /usr/local/mysql/sbin  
  2. cd /usr/local/  
  3. ./mysql-galera -g  gcomm://  start  

 

測試是否成功啟動方法, 查詢是否會自動啟動 4567 端口

  1. [root@db2 local]# netstat -ntl  
  2. Active Internet connections (only servers)  
  3. Proto Recv-Q Send-Q Local Address               Foreign Address             State  
  4. tcp        0      0 0.0.0.0:3306                0.0.0.0:*                   LISTEN  
  5. tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN  
  6. tcp        0      0 0.0.0.0:4567                0.0.0.0:*                   LISTEN  

 

登錄 mysql 之后,查詢當前是否啟用 galera 插件

  1. MariaDB [(none)]> show status like 'wsrep_ready';  
  2. +---------------+-------+  
  3. | Variable_name | Value |  
  4. +---------------+-------+  
  5. | wsrep_ready   | ON    |  
  6. +---------------+-------+  
  7. 1 row in set (0.00 sec)  


注,on 為已經啟動插件狀態


關閉方法

  1. cd /usr/local  
  2. ./mysql-galera stop  


其他節點加入集群方法

第一臺 (192.168.200.163) 節點已經啟動成功
第二臺 (192.168.200.171) 需要加入集群

  1. cd /usr/local/  
  2. ./mysql-galera -g  gcomm://192.168.200.163 start  


可按上述方法進行集群啟動測試, 也可以參照下面方法, 觀察集群地址是否增加兩個服務器地址

  1. MariaDB [(none)]> show status like 'wsrep_incoming_addresses';  
  2. +--------------------------+-------------------------------------------+  
  3. | Variable_name            | Value                                     |  
  4. +--------------------------+-------------------------------------------+  
  5. | wsrep_incoming_addresses | 192.168.200.171:3306,192.168.200.163:3306 |  
  6. +--------------------------+-------------------------------------------+  
  7. 1 row in set (0.00 sec)  



第三臺 (172.18.8.49) 需要加入集群

  1. cd /usr/local/  
  2. ./mysql-galera -g  gcomm://192.168.200.163,192.168.200.171 start  


第四臺 (172.18.8.50) 需要加入集群

  1. cd /usr/local/  
  2. ./mysql-galera -g  gcomm://192.168.200.163,192.168.200.171,172.18.8.49 start  


 

  1. 注: 每次集群啟動, 將會啟用數據同步機制,令每個集群中的數據同步  
  2.   
  3. 假如,集群工作期間,節點 3(172.18.8.49) 脫離集群,重啟,發生故障  
  4. 而脫機期間,節點1,2,4 仍可繼續工作  
  5. 當節點3 重新在線時,加入集群前,將會自動進行數據同步  
  6.   
  7. 重新在線方法與上文中加入節點方法一致  
  8.   
  9. 另外,假如覺得要定義所有的服務器地址麻煩,可以加入集群時候只定義其中一臺的地址,如 gcomm://192.168.200.163 集群也能夠自動在加入后添加其他集群 url地址  


常見 wsrep 參數注釋

  1. MariaDB [terry]> show status like 'wsrep%';  
  2. +----------------------------+--------------------------------------+  
  3. | Variable_name              | Value                                |  
  4. +----------------------------+--------------------------------------+  
  5. | wsrep_local_state_uuid     | bb5b9e17-66c8-11e3-86ba-96854521d205 | uuid 集群唯一標記  
  6. | wsrep_protocol_version     | 4                                    |  
  7. | wsrep_last_committed       | 16                                   | sql 提交記錄  
  8. | wsrep_replicated           | 4                                    | 隨著復制發出的次數  
  9. | wsrep_replicated_bytes     | 692                                  | 數據復制發出的字節數  
  10. | wsrep_received             | 18                                   | 數據復制接收次數  
  11. | wsrep_received_bytes       | 3070                                 | 數據復制接收的字節數  
  12. | wsrep_local_commits        | 4                                    | 本地執行的 sql  
  13. | wsrep_local_cert_failures  | 0                                    | 本地失敗事務  
  14. | wsrep_local_bf_aborts      | 0                                    |從執行事務過程被本地中斷  
  15. | wsrep_local_replays        | 0                                    |  
  16. | wsrep_local_send_queue     | 0                                    | 本地發出的隊列  
  17. | wsrep_local_send_queue_avg | 0.142857                             | 隊列平均時間間隔  
  18. | wsrep_local_recv_queue     | 0                                    | 本地接收隊列  
  19. | wsrep_local_recv_queue_avg | 0.000000                             | 本地接收時間間隔  
  20. | wsrep_flow_control_paused  | 0.000000                             |  
  21. | wsrep_flow_control_sent    | 0                                    |  
  22. | wsrep_flow_control_recv    | 0                                    |  
  23. | wsrep_cert_deps_distance   | 0.000000                             | 并發數量   
  24. | wsrep_apply_oooe           | 0.000000                             |  
  25. | wsrep_apply_oool           | 0.000000                             |  
  26. | wsrep_apply_window         | 1.000000                             |  
  27. | wsrep_commit_oooe          | 0.000000                             |  
  28. | wsrep_commit_oool          | 0.000000                             |  
  29. | wsrep_commit_window        | 1.000000                             |  
  30. | wsrep_local_state          | 4                                    |  
  31. | wsrep_local_state_comment  | Synced                               |  
  32. | wsrep_cert_index_size      | 0                                    |  
  33. | wsrep_causal_reads         | 0                                    |  
  34. | wsrep_incoming_addresses   | 172.18.8.50:3306,172.18.8.49:3306    | 連接中的數據庫  
  35. | wsrep_cluster_conf_id      | 18                                   |  
  36. | wsrep_cluster_size         | 2                                    | 集群成員個數  
  37. | wsrep_cluster_state_uuid   | bb5b9e17-66c8-11e3-86ba-96854521d205 | 集群 ID  
  38. | wsrep_cluster_status       | Primary                              | 主服務器  
  39. | wsrep_connected            | ON                                   | 當前是否連接中  
  40. | wsrep_local_index          | 1                                    |  
  41. | wsrep_provider_name        | Galera                               |  
  42. | wsrep_provider_vendor      | Codership Oy <info@codership.com>    |  
  43. | wsrep_provider_version     | 2.7(rXXXX)                           |  
  44. | wsrep_ready                | ON                                   | 插件是否應用中  
  45. +----------------------------+--------------------------------------+  
  46. 40 rows in set (0.05 sec)  


時間關系,還沒有時間進行壓力測試,也沒有比對  galera 與  Percona XtraDB Cluster 集群之間區別

另,如使用 rpm 則十分方便,網路很多教程, 不詳細描述

 auto_increment

當更多的 MariaDB 加入到集群之后,集群中的數據庫會自動進行協調,并且自動定義偏移量, 這個比較人性化,自動化,如下描述

db1:

  1. MariaDB [(none)]> show variables like 'auto_increment%';  
  2. +--------------------------+-------+  
  3. | Variable_name            | Value |  
  4. +--------------------------+-------+  
  5. | auto_increment_increment | 4     |  
  6. | auto_increment_offset    | 3     |  
  7. +--------------------------+-------+  
  8. 2 rows in set (0.00 sec)  


db2:

  1. MariaDB [(none)]> show variables like 'auto_increment%';  
  2. +--------------------------+-------+  
  3. | Variable_name            | Value |  
  4. +--------------------------+-------+  
  5. | auto_increment_increment | 4     |  
  6. | auto_increment_offset    | 4     |  
  7. +------------------------  


db3:

  1. MariaDB [(none)]> show variables like 'auto_increment%';  
  2. +--------------------------+-------+  
  3. | Variable_name            | Value |  
  4. +--------------------------+-------+  
  5. | auto_increment_increment | 4     |  
  6. | auto_increment_offset    | 2     |  
  7. +--------------------------+-------+  
  8. 2 rows in set (0.00 sec)  


db4:

  1. MariaDB [(none)]> show variables like 'auto_increment%';  
  2. +--------------------------+-------+  
  3. | Variable_name            | Value |  
  4. +--------------------------+-------+  
  5. | auto_increment_increment | 4     |  
  6. | auto_increment_offset    | 1     |  
  7. +--------------------------+-------+  
  8. 2 rows in set (0.00 sec)  


當前加入集群中共 4 個節點, 如上所見,每個集群中都會每次在數字遞增時候遞增 4 位, 而數字起始值為加入集群的順序 

 
模擬測試1

創建測試表

  1. MariaDB [(none)]> desc terry.t2;  
  2. +-------+-------------+------+-----+-------------------+-----------------------------+  
  3. | Field | Type        | Null | Key | Default           | Extra                       |  
  4. +-------+-------------+------+-----+-------------------+-----------------------------+  
  5. | id    | int(11)     | NO   | PRI | NULL              | auto_increment              |  
  6. | name  | varchar(20) | YES  |     | NULL              |                             |  
  7. | time  | timestamp   | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |  
  8. +-------+-------------+------+-----+-------------------+-----------------------------+  
  9. 3 rows in set (0.00 sec)  

 

在每臺電腦中創建對應的數據插入腳本  (太大量的并發插入會導致服務器不斷脫離集群,最終只剩下一次,因此減少數據插入量)

  1. [root@db6 mdb]# cat /tmp/in.sh  
  2. #!/bin/bash  
  3. for (( a=1 ; a<=1000 ; a++ ))  
  4. do  
  5.         name="db6.$a"  
  6.         mysql -u terry -p123 -e "insert into terry.t2 (name, time) values (\"$name\", now())"  
  7. done  


目的:同時在 4 臺電腦中進行數據插入,每臺插入 1000 行(并發執行)

插入過程中, 會出現鎖,有一個數據庫集群會自動脫離集群  >_<"

  1. MySQL thread id 16, OS thread handle 0x7f2f2019a700, query id 4666 applied write set 183192  
  2. TABLE LOCK table `terry`.`t2` trx id 2D3EF lock mode IX  
  3. ---TRANSACTION 2D3EE, ACTIVE 0 sec  
  4. mysql tables in use 1, locked 1  
  5. 1 lock struct(s), heap size 376, 0 row lock(s), undo log entries 1  
  6. MySQL thread id 633, OS thread handle 0x7f2f20076700, query id 4664 localhost terry query end  
  7. insert into terry.t2 (name, time) values ("db5.603", now())  
  8. TABLE LOCK table `terry`.`t2` trx id 2D3EE lock mode IX  
  9. ---TRANSACTION 2D3ED, ACTIVE (PREPARED) 0 sec preparing  
  10. 1 lock struct(s), heap size 376, 0 row lock(s), undo log entries 1  
  11. MySQL thread id 3, OS thread handle 0x7f2f3be4e700, query id 4662 committing 183190  

 

參考其他三臺 時間返回值
db1 (使用 13 秒)
db2 (使用 24秒)
db3(使用14秒)
db4(寫入 35 條數據后 crash)