本文仅适用于在无法使用其他手段恢复TxSQL服务的情况下使用,例如当多数TxSQL节点出现了数据损坏、多数派节点的IP被修改等导致集群的服务完全无法恢复的情况。
PS:新集群没数据直接走 2、3、8步。
原理
1、从流水最大的TxSQL节点的MySQL中备份数据。本步需要按照特殊方法启动pod内的mysql服务。如果IP地址修改了,可以在备份数据之前中把mysql.user表中对应IP地址修改为对应的新的IP地址,然后再执行备份。
2、重新配置TxSQL服务。前提是Manager的IP配置已经修改好,如果没有修改好,请按照这个文档修改:TDH 5.* 更改IP
3、删除TxSQL每个节点上的数据目录,以强制TxSQL在下次重启时根据当前配置重新初始化服务。
4、导入数据。
注意:下面code block中的命令和脚本都是示例,不能直接cp到生产上用。具体操作指令以本地环境与配置为准
操作步骤
1、首先启动txsql服务所有的pod。一般来说,pod启动后会自动启动其内部的txsql进程。通过 ps -ef | grep mysqld 来找到该pod里mysqld的启动命令。例如:
[root@zqdai-c02 /]# ps -ef | grep mysqld
root 262 1 0 09:33 ? 00:00:00 sh /usr/bin/txsql/bin/mysqld_safe --defaults-file=/usr/bin/txsql/etc/my.cnf --super_read_only
mysql 1595 262 0 09:33 ? 00:00:01 /usr/bin/txsql/sbin/mysqld --defaults-file=/usr/bin/txsql/etc/my.cnf --basedir=/usr/bin/txsql/percona.src --datadir=/var/txdata/percona.workspace/data --plugin-dir=/usr/bin/txsql/percona.src/lib/mysql/plugin --user=mysql --super-read-only --log-error=/var/log/txsql1/my.err --pid-file=/var/txdata/percona.workspace/data/percona.pid --socket=/var/txdata/percona.workspace/tmp/percona.sock --port=13306
root 2687 2674 0 09:40 ? 00:00:00 grep --color=auto mysqld
如果没有自动启动,则需要按照以下方法手动启动:
[root@zqdai-c02 /]# cd /usr/bin/txsql/tools
[root@zqdai-c02 tools]# ./txsql.sh start mysql
[root@zqdai-c02 tools]# ps -ef | grep mysql
root 262 1 0 09:33 ? 00:00:00 sh /usr/bin/txsql/bin/mysqld_safe --defaults-file=/usr/bin/txsql/etc/my.cnf --super_read_only
mysql 1595 262 0 09:33 ? 00:00:01 /usr/bin/txsql/sbin/mysqld --defaults-file=/usr/bin/txsql/etc/my.cnf --basedir=/usr/bin/txsql/percona.src --datadir=/var/txdata/percona.workspace/data --plugin-dir=/usr/bin/txsql/percona.src/lib/mysql/plugin --user=mysql --super-read-only --log-error=/var/log/txsql1/my.err --pid-file=/var/txdata/percona.workspace/data/percona.pid --socket=/var/txdata/percona.workspace/tmp/percona.sock --port=13306
root 2687 2674 0 09:40 ? 00:00:00 grep --color=auto mysqld
注意:mysqld的进程(/usr/bin/txsql/sbin/mysqld --defa ...... socket --port=13306)需要复制到文本中,第4步会用到
2、在所有pod里,修改脚本 /usr/bin/txsql/tools/txsql.sh,在restart_role函数内首行添加 return 0,这是为了禁止pod自动重启TxSQL服务。
以下是使用vim辑后的结果。
vim /usr/bin/txsql/tools/txsql.sh
# Helper for act_start
restart_role()
{
return 0
if [ $# -ne 1 ]; then
return 1
fi
if [ $OPT_FORCE = "N" ]; then
phx_is_role_running_by_name "$1"
[ $? -eq 0 ] && return 0
fi
# zqdai: change directory to tools to ensure the python scripts work as expected
local lPwd=$(pwd)
if [ -x "$PHX_HOME/tools" ]; then
cd "$PHX_HOME/tools"
python restart.py -p "$1"
cd "$lPwd"
else
return 1
fi
return 0
}
3、停止所有pod的txsql服务。在每个pod的目录 /usr/bin/txsql/tools 下执行 ./txsql.sh kill。例如
[root@zqdai-c02 tools]# ./txsql.sh kill
Namespace(base_dir='/usr/bin/txsql/', new_process='', process_name='mysql')
kill -9 262 1595
Namespace(base_dir='/usr/bin/txsql/', new_process='', process_name='phxsqlproxy')
kill -9 312
Namespace(base_dir='/usr/bin/txsql/', new_process='', process_name='phxbinlogsvr')
kill -9 264
4、使用以下方法启动mysql:在现场第一步中得到的mysqld的命令行参数的基础上增加参数 --rpl_phx_sync_master=OFF ,并在末尾增加 & 来启动mysqld(后台运行)。ps -ef 以验证mysql已经正常启动。在本例中,应该使用如下命令启动(注意这里是个示例,切不可直接拷贝以下命令在现场执行):
[root@zqdai-c02 /]# /usr/bin/txsql/sbin/mysqld --defaults-file=/usr/bin/txsql/etc/my.cnf --basedir=/usr/bin/txsql/percona.src --datadir=/var/txdata/percona.workspace/data --plugin-dir=/usr/bin/txsql/percona.src/lib/mysql/plugin --user=mysql --super-read-only --log-error=/var/log/txsql1/my.err --pid-file=/var/txdata/percona.workspace/data/percona.pid --socket=/var/txdata/percona.workspace/tmp/percona.sock --port=13306 --rpl_phx_sync_master=OFF &
[root@zqdai-c02 tools]# ps -ef | grep mysqld
mysql 4216 2674 1 09:54 ? 00:00:00 /usr/bin/txsql/sbin/mysqld --defaults-file=/usr/bin/txsql/etc/my.cnf --basedir=/usr/bin/txsql/percona.src --datadir=/var/txdata/percona.workspace/data --plugin-dir=/usr/bin/txsql/percona.src/lib/mysql/plugin --user=mysql --super-read-only --log-error=/var/log/txsql1/my.err --pid-file=/var/txdata/percona.workspace/data/percona.pid --socket=/var/txdata/percona.workspace/tmp/percona.sock --port=13306 --rpl_phx_sync_master=OFF
5、选择含有最新的数据(流水最大)的mysql节点。必须启动所有的pod的mysql并比较其流水的大小,否则可能有数据丢失,不应该继续操作。比较流水大小的方法:
把mysql启动起来之后,使用socket方式登录mysql,见下例,socket参数实际上是从刚才启动mysqld的命令行参数中获得的。root密码是服务部署时随机生成的,它可以从 /usr/bin/txsql/etc/db.properties 中获得,新版txsql通过 kubectl get pods $podName -oyaml | grep -i pass -A 2 获取。
执行show master status\G,在输出中,Executed_Gtid_Set是当前这个节点已经执行过的binlog集合,它一般是多条 <UUID>: <START>-<END> 的形式,又被称为流水,UUID是产生这条binlog的节点ID,START一般是1,END是每同步一个新的binlog就会+1的正整数,START-END就代表了一个正整数的区间 。在下例中,可见该节点目前已经执行了ID为35bc369c-b31e-11e7-a830-c85b762a0965的服务器上的第1-180个binlog。这个集合可能包括来自多个服务器上的binlog,此时会有以逗号分割的多条这种形式的记录 。我们必须选择一个包含的binlog最多(即所有的条目中END数值均为最大)的mysql来作为数据备份的对象,因为它包含最新的数据。
执行 mysql --socket=${txsqldata目录(可以在配置文件install_conf.sh上查看)} -p ${你的mysql的root密码}。
举例如下:
[root@zqdai-c02 tools]# mysql --socket=/var/txdata/percona.workspace/tmp/percona.sock -p'你的mysql的root密码'
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000004
Position: 191
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 35bc369c-b31e-11e7-a830-c85b762a0965:1-180
1 row in set (0.00 sec)
NOTE:如果root的密码通过manager 模板被别人修改,但是txsql中的root用户密码却没有被更改,如果没有特意记录修改之前的密码,此时将无法得知之前的密码了。具体表现为通过 mysql --socket=/var/txdata/percona.workspace/tmp/percona.sock -p'你的mysql的root密码' 该命令无法登录,显示密码不正确。
此时可以通过 --skip-grant-tables 参数重启mysql实例,跳过密码验证来备份数据。
首先,关闭实例
这里,通过kill mysqld进程的方式,查看进程方式 ps -ef | grep mysqld。
注意:不是mysqld_safe进程,也切忌使用kill -9。
- 加上--skip-grant-tables 重启mysql服务
/usr/bin/txsql/sbin/mysqld --defaults-file=/usr/bin/txsql/etc/my.cnf --basedir=/usr/bin/txsql/percona.src --datadir=/var/txdata/percona.workspace/data --plugin-dir=/usr/bin/txsql/percona.src/lib/mysql/plugin --user=mysql --super-read-only --log-error=/var/log/txsql1/my.err --pid-file=/var/txdata/percona.workspace/data/percona.pid --socket=/var/txdata/percona.workspace/tmp/percona.sock --port=13306 --rpl_phx_sync_master=OFF --skip-grant-tables &
登录mysql实例,此时将不在需要输入密码
执行 mysql --socket=${txsqldata目录(可以在配置文件install_conf.sh上查看)} 。
举例如下:
[root@zqdai-c02 tools]# mysql --socket=/var/txdata/percona.workspace/tmp/percona.sock
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000004
Position: 191
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 35bc369c-b31e-11e7-a830-c85b762a0965:1-180
1 row in set (0.00 sec)
- 这里注意如果是这种情况的话,到时候第9步恢复数据时将需要特殊处理,按照其下方的 特殊情况处理 的说明将dump出来的文件alldata.sql 中的 mysql数据库 重命名为mysql2数据库,因为mysql数据库中保存了用户名和密码,该库不应该被恢复。
5.1 (如果需要的话)修改IP地址
因IP发生变更的环境中,建议执行本步骤。在流水最大的节点上,登录到mysql之后,修改mysq.user中host列的IP地址,将旧的IP地址更改为新的IP地址:
mysql> set global super_read_only=0;
mysql> set global read_only=0;
mysql> set sql_log_bin=0;
mysql> update mysql.user set host = new_ip where host = old_ip;
6、备份数据
6.1 如果你的IP地址发生了修改,在备份数据前要登录mysql(登录方法在第5步中)并将 mysql.user 中 host一列中对应的IP地址对应地修改为新的IP地址,即 update mysql.user set host = 'new_ip' where host = 'old_ip'; 所有IP发生修改的host都要修改。select user, host from mysql.user 来确认修改成功。
6.2 获取mysql root密码
6.2.1 TDH 622之前,可以 /usr/bin/txsql/etc/db.properties 中获得。 password="xxxx",xxx就是密码
6.2.2 TDH 622及其之后,在pod里执行echo $TXSQL_DB_PASSWORD,或者在pod外,kubectl get pod xxx -oyaml |grep -i pass -A 3,其中xxx是txsql的pod
6.2 在流水最大的节点上,保持mysql的启动状态,并使用mysqldump工具备份数据,命令如下,其中port是/usr/bin/txsql/etc/install_conf.sh配置文件中的MYSQL_LOCAL_PORT,密码是服务部署时随机生成的,获取方式见步骤6.2 获取mysql root密码。备份后,请务必将备份的数据拷贝到pod之外、安全的目录下!!!
如果IP地址在部署前后发生了变化,备份之前需要把mysql.user表中host列中的IP地址改为对应的新IP地址。
[root@zqdai-c02 tools]# /usr/bin/txsql/percona.src/bin/mysqldump -h<host-ip> -P<port> -uroot -p<password> --set-gtid-purged=off --triggers --routines --events --all-databases >alldata.sql
7、重新配置服务(只适用于IP地址被修改的情况)
本步骤要求manager中存储的IP信息已经修改,如果没有修改,请先按照更换IP文档操作。
在manager中(web界面8180端口),打开TxSQL服务,选择配置服务,以便重新生成配置文件。配置文件生成后,进入每个pod,检查 /usr/bin/txsql/etc/install_conf.sh 和 /usr/bin/txsql/etc/txsql-env.sh中的IP地址信息是否正确。
8、强制TxSQL重新初始化。
删除每个pod的数据目录内的全部内容(可以从/usr/bin/txsql/etc/install_conf.sh 的DATA_DIR参数来获取,本例中这个目录是 /var/txdata/)。删除之后在manager web界面重启txsql所有的pod。大约10分钟后,txsql服务被重新部署。
[root@zqdai-c02 tools] ./txsql.sh kill # 首先停止pod内所有服务
[root@zqdai-c02 tools] cd /var/txdata/
[root@zqdai-c02 txdata] # 再次提醒,危险操作,请确保备份的数据已经存储在pod之外的安全的目录下!!
[root@zqdai-c02 txdata] mv percona.workspace percona.workspace.bak
[root@zqdai-c02 txdata] mv phxbinlogsvr phxbinlogsvr.bak
[root@zqdai-c02 txdata] rm -rf init_done.flag
删除后,在manager web界面,重启所有TxSQL的pod,大约10分钟后重启完成后,此时TxSQL应该处于健康的状态。
9、恢复数据
重新部署成功后,进入某个txsql的pod,cd /usr/bin/txsql/tools,执行 ./txsql.sh shell 登录 txsql, 然后source alldata.sql 将刚才dump的数据导入。最后执行 flush privileges 强制mysql刷新用户权限。注意要source两次
[root@zqdai-c02 tools]# ./txsql.sh shell
# 注意要source两次,第一次source之后执行 flush privileges; 然后再source一次
mysql> source alldata.sql
mysql> flush privileges;
mysql> source alldata.sql
10、删除第8步的备份的数据(确保恢复成功后再删除)
删除每个pod的数据目录中之前备份的数据(可以从/usr/bin/txsql/etc/install_conf.sh 的DATA_DIR参数来获取,本例中这个目录是 /var/txdata/)
[root@zqdai-c02 txdata] rm -rf percona.workspace.bak
[root@zqdai-c02 txdata] rm -rf phxbinlogsvr.bak
特殊情况处理:
1)灾难恢复前,集群的root密码被修改过,具体表现为:source之后,txsql pod状态从1/1变为0/1,通过socket登入的方式进入mysql,执行select user,host,password from mysql.user后发现root密文密码与select PASSWORD('填入db.properties上的password')结果不一致。
workaround的方法:vi alldata.sql(刚刚dump出来的数据文件),找到下面两行,将文中的mysql改为mysql2
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysql` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `mysql`;
然后按照第9步操作,操作完之后需要给应用用户(如inceptoruser,具体可通过select user,host,password from mysql2.user查询)赋权,赋权语句为
GRANT ALL PRIVILEGES ON *.* TO 填入你需要赋权的用户名@'%' IDENTIFIED BY '填入用户的密码,默认password';
10、检查操作状态
检查txsql的流水,确保所有节点的流水一致,即完成恢复。