天天看點

Galera/mysql 叢集

ps:先轉了,周末在container上測試玩玩。。。

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

特色

mysql/galera 是一種多主同步叢集,但隻限于使用 mysql/innodb 引擎,并具有下面特點

同步複制

多個主伺服器的拓撲結構

可以在任意節點上進行讀寫

自動控制成員,自動删除故障節點

自動加入節點

真正給予行級别的并發複制

排程客戶連接配接

優勢

參考下面基于 dbms 叢集的解決方法

不存在從伺服器角色

不存在事務丢失

讀寫操作可根據需要進行随意擴充

更少的闩操作

知識點

mysql/galera 叢集使用 galera 庫執行複制,對應 galera 複制接口,我們需要mysql 伺服器支援 wsrep api 接口

<a target="_blank" href="http://www.codership.com/products/mysql-write-set-replication-project">http://www.codership.com/products/mysql-write-set-replication-project</a>

是否可以使用 mysql 而不使用 mariadb?

不可以,因為 mysql 中沒有支援 wsrep_ 資料複制的參數,當然代碼級别上也具有很大差别

工作原理

Galera/mysql 叢集

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 編譯步驟

<a target="_blank" href="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">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</a>

yum install -y cmake

tar xf mariadb-galera-5.5.33a.tar.gz

cd mariadb-5.5.33a/

cmake -lah

參考 cmakecache.txt 檔案中的配置資訊

Galera/mysql 叢集

cmake -dinstall_mysqldatadir:string=/mdb -dinstall_unix_addrdir:string=/var/run/mysqld/mysql5.socket  

make  

make install  

預設情況下, mariadb  安裝在  /usr/local/mysql

galera 編譯

<a target="_blank" href="https://launchpad.net/galera/2.x/23.2.7/+download/galera-23.2.7-src.tar.gz">https://launchpad.net/galera/2.x/23.2.7/+download/galera-23.2.7-src.tar.gz</a>

添加資料源

Galera/mysql 叢集

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

添加下面軟體包

Galera/mysql 叢集

yum erase -y mysql.x86_64 mysql-devel.x86_64 mysql-libs.x86_64    

yum install -y boost-devel.x86_64 libodb-boost-devel.x86_64  bzr scons  

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

Galera/mysql 叢集

cd /usr/src  

tar xf galera-23.2.7-src.tar.gz  

cd galera-23.2.7-src  

scons  

注: scons 為編譯指令

編譯後能生成 libgalera_smm.so

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

Galera/mysql 叢集

mkdir /usr/local/galera/lib -p  

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

Galera/mysql 叢集

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

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

Galera/mysql 叢集

[mysqld]  

basedir=/usr/local/mysql  

big-tables  

bind-address=0.0.0.0  

character-set-server=utf8  

datadir=/mdb  

log-error=/var/log/mysqld/mysql5-error.log  

socket=/var/run/mysqld/mysql5.socket  

pid-file=/var/run/mysqld/mysql5.pid  

port=3306  

user=mysql  

binlog_format = row  

binlog_cache_size = 1m  

character_set_server = utf8  

collation_server = utf8_general_ci  

default-storage-engine = innodb  

expire_logs_days = 10  

innodb_buffer_pool_size = 300m  

innodb_thread_concurrency = 16  

innodb_log_buffer_size = 8m  

innodb_doublewrite = 1  

innodb_file_per_table = 1  

innodb_flush_log_at_trx_commit = 2  

server-id = 1  

max_connections = 1000  

net_buffer_length = 8k  

open-files-limit = 65535  

wsrep_cluster_address = 'gcomm://192.168.200.163,192.168.200.171,172.18.8.49,172.18.8.50'  

wsrep_provider = /usr/local/galera/lib/libgalera_smm.so  

wsrep_retry_autocommit = 0  

wsrep_sst_method = rsync  

wsrep_provider_options="gcache.size=256m; gcache.page_size=256m"  

wsrep_slave_threads=16  

wsrep_cluster_name='my_cluster'  

wsrep_node_name='db5'  

wsrep_sst_auth=tt:tt123  

maridb 啟動測試

初始化資料庫

Galera/mysql 叢集

mkdir /mdb  

cd /usr/local/mysql  

./scripts/install_mysql_db --datadir=/mdb  

啟動腳本 /etc/rc.d/init.d/mysql5 確定檔案可執行權限

Galera/mysql 叢集

#!/bin/sh  

# chkconfig: 2345 64 36  

# description: a very fast and reliable sql database engine.  

&lt;p&gt;basedir=/usr/local/mysql  

datadir=/mdb&lt;/p&gt;&lt;p&gt;# default value, in seconds, afterwhich the script should timeout waiting  

# for server start.  

# value here is overriden by value in my.cnf.  

# 0 means don't wait at all  

# negative numbers mean to wait indefinitely  

service_startup_timeout=900  

startup_sleep=1&lt;/p&gt;&lt;p&gt;# lock directory for redhat / suse.  

lockdir='/var/lock/subsys'  

lock_file_path="$lockdir/mysql"&lt;/p&gt;&lt;p&gt;# the following variables are only set for letting mysql.server find things.&lt;/p&gt;&lt;p&gt;# set some defaults  

mysqld_pid_file_path=/var/run/mysqld/mysql5.pid  

if test -z "$basedir"  

then  

  basedir=/usr/local/mysql  

  bindir=/usr/local/mysql/bin  

  if test -z "$datadir"  

  then  

    datadir=/usr/local/mysql/data  

  fi  

  sbindir=/usr/local/mysql/bin  

  libexecdir=/usr/local/mysql/bin  

&lt;/p&gt;&lt;p&gt;else  

  bindir="$basedir/bin"  

    datadir="$basedir/data"  

  sbindir="$basedir/sbin"  

  if test -f "$basedir/bin/mysqld"  

    libexecdir="$basedir/bin"  

  else  

    libexecdir="$basedir/libexec"  

fi&lt;/p&gt;&lt;p&gt;# datadir_set is used to determine if datadir was set (and so should be  

# *not* set inside of the --basedir= handler.)  

datadir_set=&lt;/p&gt;&lt;p&gt;#  

# use lsb init script functions for printing messages, if possible  

#  

lsb_functions="/lib/lsb/init-functions"  

if test -f $lsb_functions ; then  

  . $lsb_functions  

else  

  log_success_msg()  

  {  

    echo " success! $@"  

  }  

  log_failure_msg()  

    echo " error! $@"  

fi&lt;/p&gt;&lt;p&gt;path="/sbin:/usr/sbin:/bin:/usr/bin:$basedir/bin"  

&lt;/p&gt;&lt;p&gt;export path&lt;/p&gt;&lt;p&gt;mode=$1    # start or stop&lt;/p&gt;&lt;p&gt;[ $# -ge 1 ] &amp;&amp; shift&lt;/p&gt;&lt;p&gt;  

other_args="$*"   # uncommon, but needed when called from an rpm upgrade action  

           # expected: "--skip-networking --skip-grant-tables"  

           # they are not checked here, intentionally, as it is the resposibility  

           # of the "spec" file author to give correct arguments only.&lt;/p&gt;&lt;p&gt;case `echo "testing\c"`,`echo -n testing` in  

    *c*,-n*) echo_n=   echo_c=     ;;  

    *c*,*)   echo_n=-n echo_c=     ;;  

    *)       echo_n=   echo_c='\c' ;;  

esac&lt;/p&gt;&lt;p&gt;parse_server_arguments() {  

  for arg do  

    case "$arg" in  

      --basedir=*)  basedir=`echo "$arg" | sed -e 's/^[^=]*=//'`  

                    bindir="$basedir/bin"  

                    if test -z "$datadir_set"; then  

                      datadir="$basedir/data"  

                    fi  

                    sbindir="$basedir/sbin"  

                    if test -f "$basedir/bin/mysqld"  

                    then  

                      libexecdir="$basedir/bin"  

                    else  

                      libexecdir="$basedir/libexec"  

                    libexecdir="$basedir/libexec"  

        ;;  

      --datadir=*)  datadir=`echo "$arg" | sed -e 's/^[^=]*=//'`  

                    datadir_set=1  

&lt;/p&gt;&lt;p&gt;        ;;  

      --pid-file=*) mysqld_pid_file_path=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;  

      --service-startup-timeout=*) service_startup_timeout=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;  

    esac  

  done  

}&lt;/p&gt;&lt;p&gt;wait_for_pid () {  

  verb="$1"           # created | removed  

  pid="$2"            # process id of the program operating on the pid-file  

  pid_file_path="$3" # path to the pid file.&lt;/p&gt;&lt;p&gt;  sst_progress_file=$datadir/sst_in_progress  

  i=0  

  avoid_race_condition="by checking again"&lt;/p&gt;&lt;p&gt;  while test $i -ne $service_startup_timeout ; do&lt;/p&gt;&lt;p&gt;    case "$verb" in  

      'created')  

        # wait for a pid-file to pop into existence.  

        test -s "$pid_file_path" &amp;&amp; i='' &amp;&amp; break  

      'removed')  

        # wait for this pid-file to disappear  

        test ! -s "$pid_file_path" &amp;&amp; i='' &amp;&amp; break  

      *)  

        echo "wait_for_pid () usage: wait_for_pid created|removed pid pid_file_path"  

        exit 1  

    esac&lt;/p&gt;&lt;p&gt;    # if server isn't running, then pid-file will never be updated  

    if test -n "$pid"; then  

      if kill -0 "$pid" 2&gt;/dev/null; then  

        :  # the server still runs  

&lt;/p&gt;&lt;p&gt;      else  

        # the server may have exited between the last pid-file check and now.  

        if test -n "$avoid_race_condition"; then  

          avoid_race_condition=""  

          continue  # check again.  

        fi&lt;/p&gt;&lt;p&gt;        # there's nothing that will affect the file.  

        log_failure_msg "the server quit without updating pid file ($pid_file_path)."  

        return 1  # not waiting any more.  

      fi  

    fi&lt;/p&gt;&lt;p&gt;    if test -e $sst_progress_file &amp;&amp; [ $startup_sleep -ne 100 ];then  

        echo $echo_n "sst in progress, setting sleep higher"  

        startup_sleep=100  

    fi&lt;/p&gt;&lt;p&gt;    echo $echo_n ".$echo_c"  

    i=`expr $i + 1`  

    sleep $startup_sleep&lt;/p&gt;&lt;p&gt;  done&lt;/p&gt;&lt;p&gt;  if test -z "$i" ; then  

    log_success_msg  

    return 0  

    log_failure_msg  

    return 1  

}&lt;/p&gt;&lt;p&gt;# get arguments from the my.cnf file,  

# the only group, which is read from now on is [mysqld]  

if test -x ./bin/my_print_defaults  

&lt;/p&gt;&lt;p&gt;  print_defaults="./bin/my_print_defaults"  

elif test -x $bindir/my_print_defaults  

  print_defaults="$bindir/my_print_defaults"  

elif test -x $bindir/mysql_print_defaults  

  print_defaults="$bindir/mysql_print_defaults"  

  # try to find basedir in /etc/my.cnf  

  conf=/usr/local/mysql/etc/my.cnf  

  print_defaults=  

  if test -r $conf  

    subpat='^[^=]*basedir[^=]*=\(.*\)$'  

    dirs=`sed -e "/$subpat/!d" -e 's//\1/' $conf`  

    for d in $dirs  

    do  

      d=`echo $d | sed -e 's/[  ]//g'`  

      if test -x "$d/bin/my_print_defaults"  

      then  

        print_defaults="$d/bin/my_print_defaults"  

        break  

      if test -x "$d/bin/mysql_print_defaults"  

        print_defaults="$d/bin/mysql_print_defaults"  

    done  

  fi&lt;/p&gt;&lt;p&gt;  # hope it's in the path ... but i doubt it  

  test -z "$print_defaults" &amp;&amp; print_defaults="my_print_defaults"  

fi&lt;/p&gt;&lt;p&gt;#  

# read defaults file from 'basedir'.   if there is no defaults file there  

&lt;/p&gt;&lt;p&gt;# check if it's in the old (depricated) place (datadir) and read it from there  

#&lt;/p&gt;&lt;p&gt;extra_args=""  

if test -r "$basedir/my.cnf"  

  extra_args="-e $basedir/my.cnf"  

  if test -r "$datadir/my.cnf"  

    extra_args="-e $datadir/my.cnf"  

fi&lt;/p&gt;&lt;p&gt;parse_server_arguments `$print_defaults $extra_args mysqld server mysql_server mysql.server`&lt;/p&gt;&lt;p&gt;#  

# set pid file if not given  

if test -z "$mysqld_pid_file_path"  

  mysqld_pid_file_path=$datadir/`hostname`.pid  

  case "$mysqld_pid_file_path" in  

    /* ) ;;  

    * )  mysqld_pid_file_path="$datadir/$mysqld_pid_file_path" ;;  

  esac  

fi&lt;/p&gt;&lt;p&gt;case "$mode" in  

  'start')  

    # start daemon&lt;/p&gt;&lt;p&gt;    # safeguard (relative paths, core dumps..)  

    cd $basedir&lt;/p&gt;&lt;p&gt;    echo $echo_n "starting mysql"  

&lt;/p&gt;&lt;p&gt;    if test -x $bindir/mysqld_safe  

    then  

      # give extra arguments to mysqld with the my.cnf file. this script  

      # may be overwritten at next upgrade.  

      $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args &gt;/dev/null 2&gt;&amp;1 &amp;  

      wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$?&lt;/p&gt;&lt;p&gt;      # make lock for redhat / suse  

      if test -w "$lockdir"  

        touch "$lock_file_path"  

      fi&lt;/p&gt;&lt;p&gt;      exit $return_value  

    else  

      log_failure_msg "couldn't find mysql server ($bindir/mysqld_safe)"  

    fi  

    ;;&lt;/p&gt;&lt;p&gt;  'stop')  

    # stop daemon. we use a signal here to avoid having to know the  

    # root password.&lt;/p&gt;&lt;p&gt;    if test -s "$mysqld_pid_file_path"  

      mysqld_pid=`cat "$mysqld_pid_file_path"`&lt;/p&gt;&lt;p&gt;      if (kill -0 $mysqld_pid 2&gt;/dev/null)  

        echo $echo_n "shutting down mysql"  

        kill $mysqld_pid  

        # mysqld should remove the pid file when it exits, so wait for it.  

        wait_for_pid removed "$mysqld_pid" "$mysqld_pid_file_path"; return_value=$?  

      else  

        log_failure_msg "mysql server process #$mysqld_pid is not running!"  

        rm "$mysqld_pid_file_path"  

&lt;/p&gt;&lt;p&gt;      # delete lock for redhat / suse  

      if test -f "$lock_file_path"  

        rm -f "$lock_file_path"  

      exit $return_value  

      log_failure_msg "mysql server pid file could not be found!"  

    ;;&lt;/p&gt;&lt;p&gt;  'restart')  

    # stop the service and regardless of whether it was  

    # running or not, start it again.  

    if $0 stop  $other_args; then  

      $0 start $other_args  

      log_failure_msg "failed to stop running server, so refusing to try to start."  

      exit 1  

    ;;&lt;/p&gt;&lt;p&gt;  'reload'|'force-reload')  

    if test -s "$mysqld_pid_file_path" ; then  

      read mysqld_pid &lt;  "$mysqld_pid_file_path"  

      kill -hup $mysqld_pid &amp;&amp; log_success_msg "reloading service mysql"  

      touch "$mysqld_pid_file_path"  

      log_failure_msg "mysql pid file could not be found!"  

    ;;  

  'status')  

    # first, check to see if pid file exists  

      read mysqld_pid &lt; "$mysqld_pid_file_path"  

&lt;/p&gt;&lt;p&gt;      if kill -0 $mysqld_pid 2&gt;/dev/null ; then  

        log_success_msg "mysql running ($mysqld_pid)"  

        exit 0  

        log_failure_msg "mysql is not running, but pid file exists"  

      # try to find appropriate mysqld process  

      mysqld_pid=`pidof $libexecdir/mysqld`&lt;/p&gt;&lt;p&gt;      # test if multiple pids exist  

      pid_count=`echo $mysqld_pid | wc -w`  

      if test $pid_count -gt 1 ; then  

        log_failure_msg "multiple mysql running but pid file could not be found ($mysqld_pid)"  

        exit 5  

      elif test -z $mysqld_pid ; then  

        if test -f "$lock_file_path" ; then  

          log_failure_msg "mysql is not running, but lock file ($lock_file_path) exists"  

          exit 2  

        fi  

        log_failure_msg "mysql is not running"  

        exit 3  

        log_failure_msg "mysql is running but pid file could not be found"  

        exit 4  

  'configtest')  

    # safeguard (relative paths, core dumps..)  

    cd $basedir  

    echo $echo_n "testing mysql configuration syntax"  

    daemon=$bindir/mysqld  

    if test -x $libexecdir/mysqld  

      daemon=$libexecdir/mysqld  

    elif test -x $sbindir/mysqld  

      daemon=$sbindir/mysqld  

    elif test -x `which mysqld`  

      daemon=`which mysqld`  

      log_failure_msg "unable to locate the mysqld binary!"  

    help_out=`$daemon --help 2&gt;&amp;1`; r=$?  

    if test "$r" != 0 ; then  

      log_failure_msg "$help_out"  

      log_failure_msg "there are syntax errors in the server configuration. please fix them!"  

      log_success_msg "syntax ok"  

    exit $r  

  'bootstrap')  

      # bootstrap the cluster, start the first node  

      # that initiate the cluster  

      echo $echo_n "bootstrapping the cluster"  

      $0 start $other_args --wsrep-new-cluster  

      ;;  

  *)  

      # usage  

      basename=`basename "$0"`  

      echo "usage: $basename  {start|stop|restart|reload|force-reload|status|configtest|bootstrap}  [ mysql server options ]"  

esac&lt;/p&gt;&lt;p&gt;exit 0  

&lt;/p&gt;  

啟動每一台資料庫

Galera/mysql 叢集

service mysql5 start  

在每台資料庫中建立下面使用者, 用于 sst 認證 (以 root 登入 mysql 資料庫後執行下面的 sql 語句) 

Galera/mysql 叢集

grant usage on *.* to tt@'%' identified by 'tt123';  

grant all privileges on *.* to tt@'%';  

grant usage on *.* to tt@'localhost' identified by 'tt123';  

grant all privileges on *.* to tt@'localhost';  

flush privileges;  

關閉所有資料庫, 叢集啟動前, 不需要啟動任何一台的資料庫

Galera/mysql 叢集

service mysql5 stop  

建立并加入叢集

叢集中第一個節點啟動 (192.168.200.163)

建立軟連結,并啟動叢集,叢集啟動過程中會自動啟動 mariadb

Galera/mysql 叢集

ln -s /usr/local/mysql/bin/ /usr/local/mysql/sbin  

cd /usr/local/  

./mysql-galera -g  gcomm://  start  

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

Galera/mysql 叢集

[root@db2 local]# netstat -ntl  

active internet connections (only servers)  

proto recv-q send-q local address               foreign address             state  

tcp        0      0 0.0.0.0:3306                0.0.0.0:*                   listen  

tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   listen  

tcp        0      0 0.0.0.0:4567                0.0.0.0:*                   listen  

登入 mysql 之後,查詢目前是否啟用 galera 插件

Galera/mysql 叢集

mariadb [(none)]&gt; show status like 'wsrep_ready';  

+---------------+-------+  

| variable_name | value |  

| wsrep_ready   | on    |  

1 row in set (0.00 sec)  

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

關閉方法

Galera/mysql 叢集

cd /usr/local  

./mysql-galera stop  

其他節點加入叢集方法

第一台 (192.168.200.163) 節點已經啟動成功

第二台 (192.168.200.171) 需要加入叢集

Galera/mysql 叢集

./mysql-galera -g  gcomm://192.168.200.163 start  

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

Galera/mysql 叢集

mariadb [(none)]&gt; show status like 'wsrep_incoming_addresses';  

+--------------------------+-------------------------------------------+  

| variable_name            | value                                     |  

| wsrep_incoming_addresses | 192.168.200.171:3306,192.168.200.163:3306 |  

第三台 (172.18.8.49) 需要加入叢集

Galera/mysql 叢集

./mysql-galera -g  gcomm://192.168.200.163,192.168.200.171 start  

第四台 (172.18.8.50) 需要加入叢集

Galera/mysql 叢集

./mysql-galera -g  gcomm://192.168.200.163,192.168.200.171,172.18.8.49 start  

Galera/mysql 叢集

注: 每次叢集啟動, 将會啟用資料同步機制,令每個叢集中的資料同步  

假如,叢集工作期間,節點 3(172.18.8.49) 脫離叢集,重新開機,發生故障  

而脫機期間,節點1,2,4 仍可繼續工作  

當節點3 重新線上時,加入叢集前,将會自動進行資料同步  

重新線上方法與上文中加入節點方法一緻  

另外,假如覺得要定義所有的伺服器位址麻煩,可以加入叢集時候隻定義其中一台的位址,如 gcomm://192.168.200.163 叢集也能夠自動在加入後添加其他叢集 url位址  

常見 wsrep 參數注釋

Galera/mysql 叢集

mariadb [terry]&gt; show status like 'wsrep%';  

+----------------------------+--------------------------------------+  

| variable_name              | value                                |  

| wsrep_local_state_uuid     | bb5b9e17-66c8-11e3-86ba-96854521d205 | uuid 叢集唯一标記  

| wsrep_protocol_version     | 4                                    |  

| wsrep_last_committed       | 16                                   | sql 送出記錄  

| wsrep_replicated           | 4                                    | 随着複制發出的次數  

| wsrep_replicated_bytes     | 692                                  | 資料複制發出的位元組數  

| wsrep_received             | 18                                   | 資料複制接收次數  

| wsrep_received_bytes       | 3070                                 | 資料複制接收的位元組數  

| wsrep_local_commits        | 4                                    | 本地執行的 sql  

| wsrep_local_cert_failures  | 0                                    | 本地失敗事務  

| wsrep_local_bf_aborts      | 0                                    |從執行事務過程被本地中斷  

| wsrep_local_replays        | 0                                    |  

| wsrep_local_send_queue     | 0                                    | 本地發出的隊列  

| wsrep_local_send_queue_avg | 0.142857                             | 隊列平均時間間隔  

| wsrep_local_recv_queue     | 0                                    | 本地接收隊列  

| wsrep_local_recv_queue_avg | 0.000000                             | 本地接收時間間隔  

| wsrep_flow_control_paused  | 0.000000                             |  

| wsrep_flow_control_sent    | 0                                    |  

| wsrep_flow_control_recv    | 0                                    |  

| wsrep_cert_deps_distance   | 0.000000                             | 并發數量   

| wsrep_apply_oooe           | 0.000000                             |  

| wsrep_apply_oool           | 0.000000                             |  

| wsrep_apply_window         | 1.000000                             |  

| wsrep_commit_oooe          | 0.000000                             |  

| wsrep_commit_oool          | 0.000000                             |  

| wsrep_commit_window        | 1.000000                             |  

| wsrep_local_state          | 4                                    |  

| wsrep_local_state_comment  | synced                               |  

| wsrep_cert_index_size      | 0                                    |  

| wsrep_causal_reads         | 0                                    |  

| wsrep_incoming_addresses   | 172.18.8.50:3306,172.18.8.49:3306    | 連接配接中的資料庫  

| wsrep_cluster_conf_id      | 18                                   |  

| wsrep_cluster_size         | 2                                    | 叢集成員個數  

| wsrep_cluster_state_uuid   | bb5b9e17-66c8-11e3-86ba-96854521d205 | 叢集 id  

| wsrep_cluster_status       | primary                              | 主伺服器  

| wsrep_connected            | on                                   | 目前是否連接配接中  

| wsrep_local_index          | 1                                    |  

| wsrep_provider_name        | galera                               |  

| wsrep_provider_vendor      | codership oy &lt;[email protected]&gt;    |  

| wsrep_provider_version     | 2.7(rxxxx)                           |  

| wsrep_ready                | on                                   | 插件是否應用中  

40 rows in set (0.05 sec)  

時間關系,還沒有時間進行壓力測試,也沒有比對  galera 與  percona xtradb cluster 叢集之間差別

另,如使用 rpm 則十分友善,網路很多教程, 不較長的描述

 auto_increment

當更多的 mariadb 加入到叢集之後,叢集中的資料庫會自動進行協調,并且自動定義偏移量, 這個比較人性化,自動化,如下描述

db1:

Galera/mysql 叢集

mariadb [(none)]&gt; show variables like 'auto_increment%';  

+--------------------------+-------+  

| variable_name            | value |  

| auto_increment_increment | 4     |  

| auto_increment_offset    | 3     |  

2 rows in set (0.00 sec)  

db2:

Galera/mysql 叢集

| auto_increment_offset    | 4     |  

+------------------------  

db3:

Galera/mysql 叢集

| auto_increment_offset    | 2     |  

db4:

Galera/mysql 叢集

| auto_increment_offset    | 1     |  

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

模拟測試1

建立測試表

Galera/mysql 叢集

mariadb [(none)]&gt; desc terry.t2;  

+-------+-------------+------+-----+-------------------+-----------------------------+  

| field | type        | null | key | default           | extra                       |  

| id    | int(11)     | no   | pri | null              | auto_increment              |  

| name  | varchar(20) | yes  |     | null              |                             |  

| time  | timestamp   | no   |     | current_timestamp | on update current_timestamp |  

3 rows in set (0.00 sec)  

在每台電腦中建立對應的資料插入腳本  (太大量的并發插入會導緻伺服器不斷脫離叢集,最終隻剩下一次,是以減少資料插入量)

Galera/mysql 叢集

[root@db6 mdb]# cat /tmp/in.sh  

#!/bin/bash  

for (( a=1 ; a&lt;=1000 ; a++ ))  

do  

        name="db6.$a"  

        mysql -u terry -p123 -e "insert into terry.t2 (name, time) values (\"$name\", now())"  

done  

目的:同時在 4 台電腦中進行資料插入,每台插入 1000 行(并發執行)

插入過程中, 會出現鎖,有一個資料庫叢集會自動脫離叢集  &gt;_&lt;"

Galera/mysql 叢集

mysql thread id 16, os thread handle 0x7f2f2019a700, query id 4666 applied write set 183192  

table lock table `terry`.`t2` trx id 2d3ef lock mode ix  

---transaction 2d3ee, active 0 sec  

mysql tables in use 1, locked 1  

1 lock struct(s), heap size 376, 0 row lock(s), undo log entries 1  

mysql thread id 633, os thread handle 0x7f2f20076700, query id 4664 localhost terry query end  

insert into terry.t2 (name, time) values ("db5.603", now())  

table lock table `terry`.`t2` trx id 2d3ee lock mode ix  

---transaction 2d3ed, active (prepared) 0 sec preparing  

mysql thread id 3, os thread handle 0x7f2f3be4e700, query id 4662 committing 183190  

參考其他三台 時間傳回值

db1 (使用 13 秒)

db2 (使用 24秒)

db3(使用14秒)

db4(寫入 35 條資料後 crash)