Galera/mysql 集群

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: PS:先转了,周末在container上测试玩玩。。。 http://blog.csdn.net/signmem/article/details/17379427 特色 MySQL/Galera 是一种多主同步集群,但只限于使用 MySQL/InnoDB 引擎,并具有下面特点 同步复制 多个主服务器的拓扑结构 可以在任意节点上进行读写 自动控制成员,自动删除故障节

PS:先转了,周末在container上测试玩玩。。。

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 文件中的配置信息

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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

添加数据源

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. baseurl=http://mirror.neu.edu.cn/fedora/epel//6Server/x86_64/  

添加下面软件包

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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 并进行编译

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. cp  /usr/src/galera-23.2.7-src/scripts/mysql/mysql-galera /usr/local  


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

[plain]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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 启动测试

初始化数据库

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. mkdir /mdb  
  2. cd /usr/local/mysql  
  3. ./scripts/install_mysql_db --datadir=/mdb  


启动脚本 /etc/rc.d/init.d/mysql5 确保文件可执行权限

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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 --basedirhandler.)  
  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>  

 

启动每一台数据库

[plain]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. service mysql5 start  


在每台数据库中建立下面用户, 用于 sst 认证 (以 root 登入 mysql 数据库后执行下面的 SQL 语句

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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;  


关闭所有数据库, 集群启动前, 不需要启动任何一台的数据库

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. service mysql5 stop  

 
创建并加入集群

集群中第一个节点启动 (192.168.200.163)
创建软链接,并启动集群,集群启动过程中会自动启动 mariadb

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. ln -s /usr/local/mysql/bin/ /usr/local/mysql/sbin  
  2. cd /usr/local/  
  3. ./mysql-galera -g  gcomm://  start  

 

测试是否成功启动方法, 查询是否会自动启动 4567 端口

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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 插件

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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 为已经启动插件状态


关闭方法

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. cd /usr/local  
  2. ./mysql-galera stop  


其他节点加入集群方法

第一台 (192.168.200.163) 节点已经启动成功
第二台 (192.168.200.171) 需要加入集群

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. cd /usr/local/  
  2. ./mysql-galera -g  gcomm://192.168.200.163 start  


可按上述方法进行集群启动测试, 也可以参照下面方法, 观察集群地址是否增加两个服务器地址

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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) 需要加入集群

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. cd /usr/local/  
  2. ./mysql-galera -g  gcomm://192.168.200.163,192.168.200.171 start  


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

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. cd /usr/local/  
  2. ./mysql-galera -g  gcomm://192.168.200.163,192.168.200.171,172.18.8.49 start  


 

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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 参数注释

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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:

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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:

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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:

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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:

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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

创建测试表

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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)  

 

在每台电脑中创建对应的数据插入脚本  (太大量的并发插入会导致服务器不断脱离集群,最终只剩下一次,因此减少数据插入量)

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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 行(并发执行)

插入过程中, 会出现锁,有一个数据库集群会自动脱离集群  >_<"

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  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)

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
3月前
|
存储 关系型数据库 MySQL
Mysql集群
Mysql集群
71 0
|
1月前
|
SQL 存储 运维
MySQL高可用性:主从复制和集群
MySQL高可用性:主从复制和集群
36 0
|
1月前
|
关系型数据库 MySQL 数据库
使用 Docker 搭建一个“一主一从”的 MySQL 读写分离集群(超详细步骤
使用 Docker 搭建一个“一主一从”的 MySQL 读写分离集群(超详细步骤
62 0
|
1月前
|
SQL 关系型数据库 MySQL
OBCP实践 - 迁移 MySQL 数据到 OceanBase 集群
OBCP实践 - 迁移MySQL数据到OceanBase集群,这是一个涉及到将现有MySQL数据库的数据和表结构迁移到OceanBase分布式数据库集群的实际操作过程。OceanBase是一款高度兼容MySQL协议的分布式数据库产品,支持在线平滑迁移,以便企业用户可以从传统的MySQL数据库平滑迁移到OceanBase,以实现更高的可用性、扩展性和性能。
39 0
|
6月前
|
关系型数据库 MySQL Nacos
生产环境下的终极指南:在生产环境部署 Nacos 集群和高可用 MySQL 使用 Docker
生产环境下的终极指南:在生产环境部署 Nacos 集群和高可用 MySQL 使用 Docker
305 0
|
2月前
|
监控 负载均衡 关系型数据库
MySQL技能完整学习列表13、MySQL高级特性——1、分区表(Partitioning)——2、复制(Replication)——3、集群(Clustering)
MySQL技能完整学习列表13、MySQL高级特性——1、分区表(Partitioning)——2、复制(Replication)——3、集群(Clustering)
53 0
|
3月前
|
弹性计算 关系型数据库 MySQL
设置PolarDB MySQL版集群IP白名单教程
设置PolarDB MySQL版集群IP白名单教程 内容: 在创建PolarDB MySQL版数据库集群后,为了保证集群的安全性,您需要设置集群的IP白名单。只有添加到白名单中的IP地址或安全组中的ECS实例才能访问该集群。本文将详细介绍如何设置IP白名单。
119 2
|
4月前
|
存储 Cloud Native 关系型数据库
云原生|kubernetes|部署MySQL一主多从复制集群(基于GTID的复制)
云原生|kubernetes|部署MySQL一主多从复制集群(基于GTID的复制)
57 0
|
4月前
|
SQL 算法 关系型数据库
mysql集群分区
mysql集群分区
17 0
|
5月前
|
负载均衡 Kubernetes 关系型数据库
更快、更准、更灵活,AnalyticDB MySQL多集群自动弹性技术解析
在全球经济增长放缓的大背景之下,企业在加强数字化建设的过程中,降本增效成为一个绕不开的话题。云原生数仓AnalyticDB MySQL湖仓版(以下简称ADB MySQL) 在发布之初提供了定时弹性功能,帮助业务有规律的客户定时升降配计算资源以节省成本。时隔一年,ADB MySQL针对用户痛点,在今年云栖大会上重磅推出Multi-Cluster弹性资源模式,它具备贴合用户负载、自动配置、性能线性提升等优点,进一步帮用户节省成本,提高计算效率。