前言
由於某些很坑的原因,需要將一台mysql里的全部數據進行遷移,並且需要遷移用戶及權限。下面記錄下用戶及權限是如何遷移的。
原理
首先,我沒找到現成的工具。。。因此只好自己搞了,好在也沒多復雜。
用戶遷移
mysql里的用戶都存在於mysql.user這張表里。可以通過SQL查詢這張表拿到host、user、authentication_string(加密后的密碼)。
然后通過SQL在新庫中創建用戶,並更新新庫中的mysql.user表里的authentication_string字段。這樣就不需要知道賬號的明文密碼了。
需要注意的是,修改完mysql.user表中的加密密碼字段后,需要執行
FLUSH PRIVILEGES
然后新的密碼才能生效
權限遷移
利用SQL語句
SHOW GRANTS FOR 'user'@'host';
可查詢指定用戶被授權過的權限,得到的直接就是一條授權語句。將此授權語句在新庫中執行即可
需要注意的是授權語句中如果有針對某個表的授權,那么當表不存在時會報錯,因此授權的遷移只能放在數據的遷移之后
完整示例腳本
# coding:utf8
import pymysql
source_mysql_client = pymysql.connect(
host=None, user=None, password="", database=None, port=3306
)
source_mysql_client.autocommit(True)
source_mysql_cursor = source_mysql_client.cursor()
target_mysql_client = pymysql.connect(
host=None, user=None, password="", database=None, port=3306
)
target_mysql_client.autocommit(True)
target_mysql_cursor = target_mysql_client.cursor()
# 需要忽略的用戶
ignore_users = ["mysql.session", "root", "mysql.sys"]
#
target_sql_list = []
sql = "select host, user, authentication_string from mysql.user"
source_mysql_cursor.execute(sql)
for host, user, authentication_string in source_mysql_cursor.fetchall():
if user in ignore_users:
continue
# 創建用戶
create_sql = "CREATE USER IF NOT EXISTS '{}'@'{}' IDENTIFIED BY 'skvnajnvr92jkfads'".format(
user, host
)
# 修改密碼
change_password_sql = "UPDATE mysql.user SET authentication_string='{}' WHERE host='{}' AND user='{}'".format(
authentication_string, host, user
)
target_sql_list.append(create_sql)
target_sql_list.append(change_password_sql)
# 授權語句獲取
grant_sql = "show grants for '{}'@'{}'".format(user, host)
source_mysql_cursor.execute(grant_sql)
grant_sql_result = source_mysql_cursor.fetchall()
target_sql_list.extend([x[0] for x in grant_sql_result])
source_mysql_cursor.close()
source_mysql_client.close()
#
target_sql_list.append("FLUSH PRIVILEGES")
for sql in target_sql_list:
r = target_mysql_cursor.execute(sql)
print(sql)
print(r)
target_mysql_cursor.close()
target_mysql_client.close()
