0x01 前言
我家里有一台1年前安装的centos,跑着一些小脚本,而这些脚本需要用到maraidb。因为当时采用了默认的分区方案,所以绝大部分的磁盘空间都在home目录下,面对日益增长的数据库,我只好迁移mariadb的data文件夹。
因为我一般会将selinux关闭,所以迁移的过程并没有任何问题,如果你系统里的selinux处于启用状态,那么我这篇文章可能不适合你。如果需要确认selinux的状态,则可以执行以下命令:
[root@mariadb-t1 ~]# sestatus SELinux status: disabled
如果显示为disable则为已关闭。
0x02 准备
一般情况下,mariadb的data文件夹会在以下路径:
[root@mariadb-t1 ~]# ll /var/lib/mysql total 176176 -rw-rw---- 1 mysql mysql 16384 Jun 4 00:13 aria_log.00000001 -rw-rw---- 1 mysql mysql 52 Jun 4 00:13 aria_log_control drwx------ 2 mysql mysql 4096 Jun 4 00:10 ccnet_db drwx------ 2 mysql mysql 4096 Jun 4 00:11 ejbca -rw-rw---- 1 mysql mysql 79691776 Jun 4 00:13 ibdata1 -rw-rw---- 1 mysql mysql 50331648 Jun 4 00:13 ib_logfile0 -rw-rw---- 1 mysql mysql 50331648 Jun 4 00:01 ib_logfile1 -rw-rw---- 1 mysql mysql 0 Jun 4 00:03 multi-master.info drwx--x--x 2 mysql mysql 4096 Jun 4 00:01 mysql drwx------ 2 mysql mysql 19 Jun 4 00:01 performance_schema drwx------ 2 mysql mysql 4096 Jun 4 00:11 seafile_db drwx------ 2 mysql mysql 19 Jun 4 00:10 seafile_t1 drwx------ 2 mysql mysql 8192 Jun 4 00:11 seahub_db
但为了安全起见,需要通过CLI确认路径:
#使用以下命令登入数据库 [root@mariadb-t1 ~]# mysql -u root -p Enter password: #检查data目录路径 MariaDB [(none)]> select @@datadir; +-----------------+ | @@datadir | +-----------------+ | /var/lib/mysql/ | +-----------------+ 1 row in set (0.00 sec)
然后关闭所有需要用到mariadb的程序,再执行以下命令关闭mariadb:
[root@mariadb-t1 ~]# systemctl stop mariadb
一定要确认mariadb已经安全地关闭,否则很有可能会使数据库损坏:
[root@mariadb-t1 ~]# systemctl status mariadb.service ● mariadb.service - MariaDB 10.1.33 database server Loaded: loaded (/usr/lib/systemd/system/mariadb.service; enabled; vendor preset: disabled) Drop-In: /etc/systemd/system/mariadb.service.d └─migrated-from-my.cnf-settings.conf Active: inactive (dead) since Mon 2018-06-04 22:34:35 CST; 38s ago Docs: man:mysqld(8) https://mariadb.com/kb/en/library/systemd/ Process: 6421 ExecStartPost=/bin/sh -c systemctl unset-environment _WSREP_START_POSITION (code=exited, status=0/SUCCESS) Process: 6393 ExecStart=/usr/sbin/mysqld $MYSQLD_OPTS $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION (code=exited, status=0/SUCCESS) Process: 6372 ExecStartPre=/bin/sh -c [ ! -e /usr/bin/galera_recovery ] && VAR= || VAR=`/usr/bin/galera_recovery`; [ $? -eq 0 ] && systemctl set-environment _WSREP_START_POSITION=$VAR || exit 1 (code=exited, status=0/SUCCESS) Process: 6370 ExecStartPre=/bin/sh -c systemctl unset-environment _WSREP_START_POSITION (code=exited, status=0/SUCCESS) Main PID: 6393 (code=exited, status=0/SUCCESS) Status: "MariaDB server is down" Jun 04 00:45:55 mariadb-t1 systemd[1]: Started MariaDB 10.1.33 database server. Jun 04 22:34:32 mariadb-t1 systemd[1]: Stopping MariaDB 10.1.33 database server... Jun 04 22:34:32 mariadb-t1 mysqld[6393]: 2018-06-04 22:34:32 140630452087552 [Note] /usr/sbin/mysqld: Normal shutdown Jun 04 22:34:32 mariadb-t1 mysqld[6393]: 2018-06-04 22:34:32 140630452087552 [Note] Event Scheduler: Purging the queue. 0 events Jun 04 22:34:32 mariadb-t1 mysqld[6393]: 2018-06-04 22:34:32 140629698934528 [Note] InnoDB: FTS optimize thread exiting. Jun 04 22:34:32 mariadb-t1 mysqld[6393]: 2018-06-04 22:34:32 140630452087552 [Note] InnoDB: Starting shutdown... Jun 04 22:34:33 mariadb-t1 mysqld[6393]: 2018-06-04 22:34:33 140630452087552 [Note] InnoDB: Waiting for page_cleaner to finish flushing of buffer pool Jun 04 22:34:35 mariadb-t1 mysqld[6393]: 2018-06-04 22:34:35 140630452087552 [Note] InnoDB: Shutdown completed; log sequence number 2940637 Jun 04 22:34:35 mariadb-t1 mysqld[6393]: 2018-06-04 22:34:35 140630452087552 [Note] /usr/sbin/mysqld: Shutdown complete Jun 04 22:34:35 mariadb-t1 systemd[1]: Stopped MariaDB 10.1.33 database server.
一定要确认最后一行出现了以上内容,否则请不要进行迁移的工作。
0x03 迁移
再三确认mariadb已经安全地关闭后,在目标路径建立新的data文件夹,在这里我以以下路径作为示例:
/mysql_database
在根目录下新建一个名为mysql_database的文件夹,并将所有权与组修改为mysql:
#新建目录 [root@mariadb-t1 ~]# mkdir /mysql_database #修改权限 [root@mariadb-t1 ~]# chown mysql:mysql /mysql_database
然后将原data目录中的所有文件同步或复制到新的目录中,在这里需要注意保留相关文件的权限。为此,这里有两种方法:
#使用cp命令复制 [root@mariadb-t1 ~]# cp -rp /var/lib/mysql/* /mysql_database/ #使用rsync命令同步 [root@mariadb-t1 ~]# rsync -av /var/lib/mysql/* /mysql_database/
如果使用cp命令则需要使用“-p”选项,以便保留文件的属性;如果使用rsync则需要使用“-a”选项,同时建议使用“-v”选项以便观察同步进度。
以上命令选一即可,完成后即可查看相关文件的属性:
#新目录中文件的属性 [root@mariadb-t1 ~]# ll /mysql_database/ total 176184 -rw-rw---- 1 mysql mysql 16384 Jun 4 22:34 aria_log.00000001 -rw-rw---- 1 mysql mysql 52 Jun 4 22:34 aria_log_control drwx------ 2 mysql mysql 4096 Jun 4 00:10 ccnet_db drwx------ 2 mysql mysql 4096 Jun 4 00:11 ejbca -rw-rw---- 1 mysql mysql 79691776 Jun 4 22:34 ibdata1 -rw-rw---- 1 mysql mysql 50331648 Jun 4 22:34 ib_logfile0 -rw-rw---- 1 mysql mysql 50331648 Jun 4 00:01 ib_logfile1 -rw-rw---- 1 mysql mysql 0 Jun 4 00:03 multi-master.info drwx--x--x 2 mysql mysql 4096 Jun 4 00:01 mysql drwx------ 2 mysql mysql 19 Jun 4 00:01 performance_schema drwx------ 2 mysql mysql 4096 Jun 4 00:11 seafile_db drwx------ 2 mysql mysql 19 Jun 4 00:10 seafile_t1 drwx------ 2 mysql mysql 8192 Jun 4 00:11 seahub_db #原目录中文件的属性 [root@mariadb-t1 ~]# ll /var/lib/mysql.bak/ total 176176 -rw-rw---- 1 mysql mysql 16384 Jun 4 00:13 aria_log.00000001 -rw-rw---- 1 mysql mysql 52 Jun 4 00:13 aria_log_control drwx------ 2 mysql mysql 4096 Jun 4 00:10 ccnet_db drwx------ 2 mysql mysql 4096 Jun 4 00:11 ejbca -rw-rw---- 1 mysql mysql 79691776 Jun 4 00:13 ibdata1 -rw-rw---- 1 mysql mysql 50331648 Jun 4 00:13 ib_logfile0 -rw-rw---- 1 mysql mysql 50331648 Jun 4 00:01 ib_logfile1 -rw-rw---- 1 mysql mysql 0 Jun 4 00:03 multi-master.info drwx--x--x 2 mysql mysql 4096 Jun 4 00:01 mysql drwx------ 2 mysql mysql 19 Jun 4 00:01 performance_schema drwx------ 2 mysql mysql 4096 Jun 4 00:11 seafile_db drwx------ 2 mysql mysql 19 Jun 4 00:10 seafile_t1 drwx------ 2 mysql mysql 8192 Jun 4 00:11 seahub_db
确认无误后,即可将原目录重命名:
[root@mariadb-t1 ~]# mv /var/lib/mysql /var/lib/mysql.bak
注意!在确认迁移成功之前请不要删除原目录,也不要使用mv命令将原目录移动至新路径中!!!
0x04 配置
完成数据的迁移后还不能启动,还需要修改mariadb的配置文件,以便让mariadb知道自己的data目录。为此,我们需要在以下文件中添加几行内容:
#打开文件 [root@mariadb-t1 ~]# vim /etc/my.cnf.d/server.cnf #在[mysqld]块中添加以下内容 datadir=/mysql_database/ socket=/mysql_database/mysql.sock
完成后的文件类似下图:
因为服务器的socket路径变了,为方面本地client的使用方便,还需要修改client的配置文件,以便让client知道socket的路径:
#打开文件 [root@mariadb-t1 ~]# vim /etc/my.cnf.d/client.cnf #在[client]块中添加以下内容 socket=/mysql_database/mysql.sock port=3306
完成后的文件如下:
至此已完成配置文件的修改,此时再打开一个console窗口,执行以下命令以便观察启动的日志:
[root@mariadb-t1 ~]# tail -f -n 1 /var/log/messages
最后执行以下命令,立即启动mariadb:
[root@mariadb-t1 ~]# systemctl restart mariadb
如果一切正常,那么通过以下命令即可发现mariadb处于运行状态:
[root@mariadb-t1 ~]# systemctl status mariadb
从箭头处也可以发现data目录也变更为我们自定义的目录,再回头查看message中的日志:
没有发现异常或告警,至此可以确认迁移成功。
0x05 其他
在centos中迁移的过程比较简单,其实也可以将data目录迁移至其他mariadb实例中,但新旧实例的版本号须一致。
而在某些情况下,如果出现类似以下的错误日志:
[Warning] Can't create test file /mysql_database/mariadb-t1.test
则可以尝试修改以下文件:
[root@mariadb-t1 ~]# vim /lib/systemd/system/mariadb.service
将[Service]块中ProtectHome的值修改为false。但升级版本后有可能使得mariadb的daemon被还原,因此可以将该配置添加至以下文件中:
#打开文件 [root@mariadb-t1 ~]# vim /etc/systemd/system/mariadb.service.d/migrated-from-my.cnf-settings.conf #在[Service]块中添加以下内容 ProtectHome = false
但通过查询相关资料发现,当mariadb的data文件放置在/home目录中才需要将上述选项设置为false。
另外,还可以将ProtectSystem设为off,具体的说明请参考以下地址:
最后还需要注意一个安全系统apparmor,这个并没有预设在centos中,因为centos有selinux,但如果你用的是OpenSUSE或Ubuntu,则需要修改以下文件:
[root@mariadb-t1 ~]# vim /usr/share/mysql/policy/apparmor/usr.sbin.mysqld
搜索/var/lib/mysql,会发现两处高亮的地方,第一处是:
/var/lib/mysql/ r, /var/lib/mysql/** rwk,
为此,我们需要照搬上面的内容,并添加到文档中:
/mysql_database/ r, /mysql_database/** rwk,
第二处如下:
/var/lib/mysql/ r, /var/lib/mysql/** rw, /var/lib/mysql/*.log w, /var/lib/mysql/*.err w,
将以下内容添加到文档中:
/mysql_database/ r, /mysql_database/** rw, /mysql_database/*.log w, /mysql_database/*.err w,
完成后需要重新启动apparmor?因为我还没配置过这个服务,所以没有更多的意见或经验。
但在centos中迁移data目录并没有那么繁琐,这里仅仅作为记录之用。
0x06 结语
唯一需要注意的是:一定要确认mariadb已经安全停止!