logo  

运维备忘录

运维备忘录
作者: 陈安廉

摘要:软件开发进阶系列


数据迁移


2023-06-14 17:33:38


迁移注意事项


在迁移之前,一定要记得备份数据,以便在迁移操作搞砸时进行恢复。而且,应该在执行迁移操作之前,停止MySQL服务器,迁移完成之后再重启它。

对于某些类型的迁移,如移动数据库目录,有时可能会保持服务器继续运行,但不推荐这样做。如果真要那样,一定要保证服务器不会访问正移动的那个数据库。在移动数据库之前,还应该执行FLUSH TABLES语句,以保证服务器会关闭所有打开的表文件。

待迁移的数据目录必须保证有充足的空间可用,避免迁移过程中将磁盘撑爆导致迁移失败。

如果不遵守这几点,可能会导致表损坏。


迁移整个数据目录


在迁移数据目录时,要停止MySQL服务器,并把数据目录移至新的位置。在移动之后,要使用能明确指示新位置的--datadir选项来重启服务器。


在Unix上,除了使用--datadir以外,还可以在原来的数据目录里创建一个符号链接,让它指向新位置。


1. 停掉 MySQL 服务


systemctl stop mysqld.service


2. 确认迁移目录


mkdir -p /data/mysql


3. 把 data 目录拷贝到目标目录 / data


cp -aR /var/lib/mysql /data/mysql


4. 修改权限 (mysql 的运行账户为 “mysql“用户),否则 MySQL 启动会报错:


chown -R mysql.mysql /data/mysql


chcon -R -t mysqld_db_t /data/mysql/mysql/


https://aiezu.com/article/mysql_selinux_config.html

5. 修改 MySQL 配置文件, 将 data 目录修改至新分区:


vim /etc/my.cnf


datadir = /data/mysql/mysql


6. 启动服务,验证服务访问是否正常


systemctl start mysqld.service


7. 备份旧数据目录


mv /opt/mysql/data /data/data-old



可能遇到权限问题

2023-06-15T03:13:02.775441Z 0 [Warning] Can't create test file /data/mysql/mysql/localhost.lower-test
2023-06-15T03:13:02.775517Z 0 [Note] /usr/sbin/mysqld (mysqld 5.7.42) starting as process 45822 ...
2023-06-15T03:13:02.778196Z 0 [Warning] Can't create test file /data/mysql/mysql/localhost.lower-test
2023-06-15T03:13:02.778227Z 0 [Warning] Can't create test file /data/mysql/mysql/localhost.lower-test
2023-06-15T03:13:02.780139Z 0 [Note] InnoDB: PUNCH HOLE support available
2023-06-15T03:13:02.780182Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2023-06-15T03:13:02.780188Z 0 [Note] InnoDB: Uses event mutexes
2023-06-15T03:13:02.780195Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
2023-06-15T03:13:02.780199Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.13
2023-06-15T03:13:02.780203Z 0 [Note] InnoDB: Using Linux native AIO
2023-06-15T03:13:02.780545Z 0 [Note] InnoDB: Number of pools: 1
2023-06-15T03:13:02.780687Z 0 [Note] InnoDB: Using CPU crc32 instructions
2023-06-15T03:13:02.782706Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
2023-06-15T03:13:02.791720Z 0 [Note] InnoDB: Completed initialization of buffer pool
2023-06-15T03:13:02.794126Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2023-06-15T03:13:02.806213Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
2023-06-15T03:13:02.813536Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2023-06-15T03:13:02.813609Z 0 [ERROR] InnoDB: Operating system error number 13 in a file operation.
2023-06-15T03:13:02.813618Z 0 [ERROR] InnoDB: The error means mysqld does not have the access rights to the directory.
2023-06-15T03:13:02.813624Z 0 [ERROR] InnoDB: Operating system error number 13 in a file operation.
2023-06-15T03:13:02.813629Z 0 [ERROR] InnoDB: The error means mysqld does not have the access rights to the directory.
2023-06-15T03:13:02.813640Z 0 [ERROR] InnoDB: Cannot open datafile './ibtmp1'
2023-06-15T03:13:02.813654Z 0 [ERROR] InnoDB: Unable to create the shared innodb_temporary
2023-06-15T03:13:02.813662Z 0 [ERROR] InnoDB: Plugin initialization aborted with error Cannot open a file
2023-06-15T03:13:03.414024Z 0 [ERROR] Plugin 'InnoDB' init function returned error.
2023-06-15T03:13:03.414038Z 0 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
2023-06-15T03:13:03.414042Z 0 [ERROR] Failed to initialize builtin plugins.
2023-06-15T03:13:03.414056Z 0 [ERROR] Aborting

2023-06-15T03:13:03.414083Z 0 [Note] Binlog end
2023-06-15T03:13:03.414161Z 0 [Note] Shutting down plugin 'CSV'
2023-06-15T03:13:03.414419Z 0 [Note] /usr/sbin/mysqld: Shutdown complete


解决:https://www.cnblogs.com/HeisenbergUncertainty/p/16343229.html


问题:如何保持selinux 的强安全模式 且 mysql 服务正常 ?
答: 修改 selinux的mysql安全配置项

1 # getsebool -a |grep mysql
2 mysql_connect_any --> off
3 selinuxuser_mysql_connect_enabled --> off


问:如何打开 配置项

1 # setsebool -P selinuxuser_mysql_connect_enabled on
2 # setsebool -P mysql_connect_any on

修改selinux为 Enforcing 后 ,mysql 服务正常 。





迁移单个数据库


服务器总是会在数据目录里查找数据库目录,因此迁移数据库的唯一方法是使用符号链接。这个过程在Unix和Windows上有所不同。


在Unix上,迁移数据库的过程如下:


(1)停止正在运行的Mysql服务。


mysqladmin -p -u root shutdown


(2)把数据库移至新的位置;或者将其复制过去,并删除原来那个。


cd /usr/local/mysql/data


tar cf - bigdb | (cd /data/mysql; tar xf -)


rm -rf bigdb


(3)在数据目录中创建一个符号链接,让其具有原来那个数据库的名字,并指向那个新的数据库位置。


ln -s /data/mysql/bigdb bigdb


(4)重启服务器。


mysqld_safe &


迁移单个表


只有在满足以下条件时才能迁移单个表:


必须使用Unix系统,并且要迁移的表必须为MylSAM表。

操作系统必须具有一个可工作的realpath()系统调用。如果真有,那么下面这个査询的结果改为YES:

          SHOW VARIABLES LIKE 'have_symlink';


 如果上述两个条件都满足,那么你便可以把表的.MYD数据文件和.MYI索引文件移动到新的位置;接着在原来的数据文件和索引文件所在的数据库目录里创建符号链接,分别指向它们。(.frm文件仍然需要留在原来的数据库目录里)。


在执行此操作之前,可以在移动文件时停止Mysql服务;也可以锁定表,以防止服务器使用它。


迁移InnoDB系统表空间


在初次配置InnoDB系统表空间时,可以使用innodb_data_home_dir和innodb_data_file_path系统变量,将InnoDB系统表空间的各个组成文件罗列在某个选项文件里。(更多相关细节请参考后面"存储引擎配置"文章)。


如果你已经创建了表空间,可能就可以迁移组成它的那些常规文件,例如,把它们分散到不同的文件系统里。因为文件的位置是通过系统变量来指定的,所以你必须按以下步骤来迁移部分或者全部的表空间文件:


(1)停止mysql服务。


(2)移动需要迁移的表空间文件。


(3)修改定义InnoDB配置的那个选项文件,修改为文件迁移后的新位置。


(4)重启mysql服务。


迁移状态文件和日志文件


如果要迁移PID文件或日志文件,则需要先停止MySQL服务器,然后使用一个可以指定文件新位置的选项来重启它。例如,为把PID文件创建为/tmp/mysql.pid,可以在命令行上使用--pid-file=/tmp/mysql.pid选项,或者在某个选项文件里包含以下内容:


[mysqld]


pid-file = /tmp/mysql.pid


如果是用绝对路径名来指定文件名,那么服务器会使用该路径名来创建文件。如果使用的是相对路径名,那么服务器将在其自己的数据目录中创建该文件。例如,当指定--pid-file=mysqld.pid时,这个PID文件即为数据目录下的mysqld.pid。


有些系统会把各种服务器的PID文件保存在某个特定的目录里,如/var/run。你可能也会想要把MySQL的PID文件保存到那里,从而与系统操作的保持一致。类似地,如果你的系统把日志文件都保存在/var/log目录里,那么你也可以把MySQL的日志文件放置到那里。不过,许多系统都只允许root用户对这些子目录进行写操作。这意味着,你必须以root用户权限来运行服务器——从安全的角度来讲,这可是个不太好的做法。比较可行的做法是:创建两个子目录/var/run/mysql和/var/log/mysql,并把它们的所有者设置成你用于运行服务器的那个账户。例如,这个账户的用户名和用户组名都是mysql,以root用户的身份执行以下命令:


mkdir /var/run/mysql


chown mysql.mysql /var/run/mysql


chmod 770 /var/run/mysql


mkdir /var/log/mysql


chown mysql.mysql /var/log/mysql


chmod 770 /var/log/mysql


然后,服务器就能毫无问题地在这些目录里写入文件了,并且可以使用指定这些文件所在位置的选项来启动服务器。例如:


[mysqld]


pid-file = /var/run/mysql/mysql.pid


log-error = /var/log/mysql/mysql.error


general_log = 1


general_log_file = /var/log/mysql/querylog


log-bin = /var/log/mysql/binlog