业务场景

最近的一个项目最开始由于资源问题,mysql 数据库是部署在一台云服务器上的,这两天客户提供了云数据库,所以原来在部署在 ECS 服务器上的数据库,需要迁移到云数据库。在云数据库上的优势很多,它自动是分配了一主二从,自动备份等。所以这两天的任务就是要将原来的数据库迁移。 mysql 版本 mysql5.7.17

迁移步骤

迁移数据库是一项需要很谨慎的任务。整个迁移过程大概分成以下几步:

  1. 备份原数据库数据
//备份数据库,并指定日期
mysqldump -uadmin -p****** databaseName | gzip > /databak/databaseName_$(date +%Y%m%d).sql.gz

  1. 云数据库上初始化数据库、编码、用户名、数据库等基础信息 先通过腾讯云平台创建用户,以及相关权限
//连接数据库
mysql -h172.16.0.1 -uUserName -p******
//创建数据库,并指定编码
CREATE DATABASE databaseName DEFAULT CHARACTER SET  utf8mb4 COLLATE utf8mb4_general_ci;

  1. 执行还原操作
//解压备份好的.sql文件
gunzip -v /databak/databaseName_20200517.sql.gz
//还原数据库
source /databak/databaseName_20200517.sql

产生的问题

正常情况下,按照以上迁移数据的步骤,应该等还原操作完成即可,但是事情往往不会那么顺利,如果很顺利可能我们对数据库迁移的认知就到这里就可以了。

实际上在执行还原操作时出现了错误。 主要出现两次问题

  1. 没有主键
ERROR 1173 (42000): This table type requires a primary key

  1. 表的存储引擎不对
Can not create tables in myisam storage engine in user databases, controled by reject_create_table_myisam variable.

看到这两个问题,感觉比较奇怪,因为最开始在测试数据库自动备份时,已经对备份的sql文件还原过,没有发现有什么错误。为什么这一次迁移就出现这两个问题呢?

排查方法

建表缺少主键

针对问题1,看日志比较容易明白意思,就是表需要主键,这个时候就想先看看数据库中有哪些没有主键的表,看看能否直接指定。

查询没有主键的表的sql如下:

SELECT table_schema, table_name,TABLE_ROWS
FROM information_schema.tables
WHERE (table_schema, table_name) NOT IN (
SELECT DISTINCT table_schema, table_name
FROM information_schema.columns
WHERE COLUMN_KEY = 'PRI'
)
AND table_schema NOT IN ('sys', 'mysql', 'information_schema', 'performance_schema');

查询结果分析发现这些表和错误日志中的表匹配。然后查看了两张表发现的确都是没有指定主键的。正常 mysql 的设计中,如果在创建表时没有显式地定义主键,则 InnoDB 存储引擎会按如下方式选择或创建主键:

  1. 首先判断表中是否有非空的唯一索引,如果有,则该列即为主键。
  2. 如果不符合上述条件,InnoDB存储引擎自动创建一个6字节大小的指针。

但是还是报那个错。这时在想是否和数据库的版本有关系。经过 google 搜索大部分的结果都是定位到数据库的参数设置了表一定要指定主键。

解决办法如下:

//查询变量查看是否开启了强制主键,也就是建表必须有主键约束,
show global variables like 'innodb_force_primary_key';
//如果是ON则设置成OFF即可
set global  innodb_force_primary_key=off;

当然我也找找这个方法去尝试了,但我执行第一句时,发现没有找到结果。然后也经过了解这个参数是mysql8.0以及MariaDB中才有这个参数。强制执行

set global  innodb_force_primary_key=off;

出现如下错误:

ERROR 1193 (HY000): Unknown system variable 'innodb_force_primary_key'

所以这种方法行不通。但通过这个解决方法,我猜测问题可能就是和变量设置有关系,于是我查看了所有的 mysql 全局变量,最后找到了问题所在。

问题定位:原来腾讯云上的分布式数据库tdsql中,设置建表需要主键的参数为 reject_table_no_pk 这个时候就能定位到问题所在了。

表的存储引擎不对

通过如下sql可以查询一个库中所有使用MyISAM存储引擎创建的表

SELECT * FROM information_schema.tables where engine='MyISAM' and TABLE_SCHEMA='databaseName'

查出来的表和还原错误日志报错的表也匹配了。

通过分析问题1时,在查找全局变量时存在如下变量。

reject_create_table_myisam 意思就是拒绝使用 myisam 存储引擎建表。所以问题2也定位到了问题源头。

解决方案

通过上面一步一步分析问题,已经找到了问题的源头,找到了问题的产生原因。对于问题的解决就比较好处理了。

方法1

登录超级管理员,对这两个参数进行设置

set global reject_table_no_pk 0;
set global reject_create_table_myisam OFF;

设置完成之后,重新执行还原操作,发现问题解决。但是分布式数据库新增了的这两个参数其实是有他的用处的,这种默认值最好不要轻易调整,因为云数据库还有一个优势就是大部分的参数都调成了最佳。

通过资料搜索发现原来这两个参数是有重要作用的。 TDSQL 内核使用 row 格式的 binlog 复制。根据目前 MariaDB/MySQL 的实现方式,如果一个 update/delete 语句更新或者删除了很多行,那么到了备机上面,更新或者删除每个行时候,需要使用索引扫描或者全表扫描来找到这个行,导致备机复制变得非常慢,这是非常严重的问题。 在 TDSQL 的告警平台上面就有用户出现过主备延迟因此变得非常大的告警。为了避免这些致命问题的出现,所以才有“自动增加主键”和“禁止 create table/alter table 语句产生无主键的表”

方法2

方法1能够解决还原问题,也能够解决一般数据量不大的应用。但是如果后面业务增长,可能还是需要将参数调整回来。此时方法1的解决方案就行不通了。

方法2实际就是针对没有主键的表设置主键,没有主键的表新增主键。以符合分布式数据库要求。

而对于数据库存储引擎为myisam的表通过sql语句直接调整。

//修改表的存储引擎
alter table table_name engine=innodb;

总结

数据库内容很多,很深,我们在处理工作中实际问题时,需要多多思考。从解决实际问题的过程中去深入知识点,扩展知识点。这样才能提高。

create 执行存储过程报错出现符号_记一次数据库迁移的过程采坑过程相关推荐

  1. create 执行存储过程报错出现符号_年薪百万之路--第四十天 存储引擎

    存储引擎 日常生活中文件格式有很多中,并且针对不同的文件格式会有对应不同存储方式和处理机制(txt,pdf,word,mp4...) 针对不同的数据应该有对应的不同的处理机制来存储 存储引擎就是不同的 ...

  2. oracle存储过程00054,oracle执行存储过程报错:ORA-12011

    执行定时任务时报错: 不一定是权限问题,但肯定是存储过程执行的问题. 我的存储过程带参数,我用测试存储过程的代码放入了job的what值,eg:proc_update_tag_cor_id(v_cor ...

  3. mysql执行存储过程报错1366_花花蘑菇

    编辑 删除 mysqld_multi安装多个mysql实例 一个机器上安装多个mysql实例,除了将每个实例在不同的目录下编译安装,为每个实例指定不同的端口,socket,配置文件,安装目录等.还可以 ...

  4. HQL语句中数据类型转换,及hibernate中createQuery执行hql报错

    一.HQL语句中数据类型转换: 我们需要从数据库中取出序号最大的记录,想到的方法就是使用order by子句进行排序(desc倒序),然后取出第一个对象,可是当初设计数据库时(我们是在原来的数据库的基 ...

  5. 执行./node_modules/,bin/sequelize migration:create --name UserInit报错无法加载

    执行./node_modules/,bin/sequelize migration:create --name UserInit报错无法加载,参考网址 后执行Set-ExecutionPolicy - ...

  6. 一次'诡异'的执行SQL报错ORA-03113的问题处理

    银行某系统存储过程报错,重新调起仍报错,而前几天这个一直正常.通过应用日志定位到报错信息, ORA-03113: 通信通道的文件结尾 进程 ID: 36503726 会话 ID: 586 序列号: 6 ...

  7. 在windows本地创建svn及遇到错误:svn create repository here 报错

    在windows本地创建svn及遇到错误:svn create repository here 报错 学习使用svn,尝试在本地创建ropository目录和working时,在创建ropositor ...

  8. 在Linux执行命令报错”Arg list too long”的原因分析

    http://www.yunweipai.com/archives/558.html 在Linux执行命令报错"Arg list too long"的原因分析 吞拿鱼手卷 于 3 ...

  9. 数据库执行sql报错Got a packet bigger than 'max_allowed_packet' bytes及重启mysql

    准备在mysql上使用数据库A,但mysql5经过重装后,上面的数据库已丢失,只得通过之前备份的A.sql重新生成数据库A. 1.执行sql报错 在执行A.sql的过程中,出现如下错误:Got a p ...

最新文章

  1. python 服务器端_python实现服务器端
  2. c语言中eof_C语言的标准 “输入输出”!今天是你学C语言的第几天?
  3. 《PHP对象、模式与实践》之高级特性
  4. Unicode 和 UTF-8 有何区别?
  5. 3、假设有一个对象数组,想根据某个对象属性对数组进行排序时
  6. 【django】HttpResponse对象
  7. multinorm r语言_与心理学数据分析相关的R工具包
  8. JS性能分析(测试代码运行时间)
  9. lua软件测试自动化,一种基于Lua脚本的嵌入式软件自动化测试系统及方法专利_专利查询 - 天眼查...
  10. 关于相似性度量与各类距离的意义
  11. sql server序列_SQL Server中身份和序列之间的区别
  12. android开发之PreferenceScreen使用详解
  13. 百度搜索引擎的搜索高级语法及应用
  14. 方舟手游机服务器修改,方舟生存进化私服怎么设置 方舟手游私服设置教程
  15. Java+HTML预习笔记_20140610
  16. 从空城计到阿尔法狗,博弈论如何渗透我们的生活?
  17. office 2021保姆级安装与激活教程(附安装包获取)
  18. Linux中vim如何配置,Linux中vim的简单配置
  19. html涟漪效果,涟漪效果.html
  20. 苹果:用Impactor安装软件时出现Line:182错误

热门文章

  1. 在struts2 中通过ActionContext访问Session对象
  2. Javascript学习历程之事件
  3. 使用Kubeadm(1.13+)快速搭建Kubernetes集群
  4. 【学习记录】第一章 数据库设计-《SQL Server数据库设计和开发基础篇视频课程》...
  5. nginx 配置反向代理和负载均衡
  6. php算法和数据结构
  7. 2018.7.28 二叉树的遍历规则(前序遍历、后序遍历、中序遍历)
  8. 2017.10.31笔记
  9. Algorithm -- 全排列
  10. [转] Android实时抓包分析 : 善用adb调试桥