云服务器内容精选

  • 开通数据库代理后,还是有大量select请求分发到主节点 原因分析: 读权重参数 设置主节点和只读节点的读权重分配,可以控制读请求的分发配比,仅在存在只读节点时生效。 例如:一主两只读,设置的读权重为1(主):2(只读1):3(只读2),那么会按照1:2:3将读请求分发到主和只读实例上;如果将读权重设置为0:2:3,会按照2:3将请求分发的只读实例,不会将读请求分发的主实例。 更多信息,请参见设置读写分离权重。 事务 事务中的SQL会发往主,若在查询语句前设置set autocommit=0也会被当做事务处理路由到主实例。 连接绑定 执行了Multi-Statements(如“insert xxx;select xxx”)当前连接的后续请求会全部路由到主节点;创建临时表的SQL会将连接绑定到主,后续此连接的请求都会到主。需断开当前连接并重新连接才能恢复读写分离。 自定义变量 SQL中包含了自定义变量的语句会发到主节点。 带锁的读操作(如SELECT for UPDATE)会被路由到主节点。 通过Hint指定SQL发往主实例或只读实例 在读写分离权重分配体系之外,在SQL开头添加hint注释进行强制路由: /*FORCE_MASTER*/:强制路由到主节点 /*FORCE_SLAVE*/:强制路由到只读节点 Hint注释仅作为路由建议,非只读SQL、事务中的场景不能强制路由到只读节点。 会话一致性特性 同一个会话内,对于写入还没有同步到只读节点的数据,读请求也会发送到主节点。 更多信息,请参见一致性级别介绍。 父主题: SQL类
  • 解决方案 方案1:可以在需要排序的字段上加上索引。如案例中,alter table ratings add index idx_category (category); 方案2:可以在排序语句的order by后面加入主键列。如案例中,select * from ratings order by category, id limit 2,2; 方案3:可以在TaurusDB控制台参数修改页面,开启参数“rds_force_stable_sort”。该参数开启后,将强制使用稳定排序算法,确保排序结果的稳定。 图1 设置参数rds_force_stable_sort
  • 解决方案 如果客户端使用了和数据库不同的字符集,需要调整客户端配置,使用相同的字符集连接数据库,或者在连上数据库后显式设置成对应的字符集,即可正常查询。 显式设置字符集的方法如下: set collation_connection = utf8mb4_general_ci; 其中“utf8mb4_general_ci”为需要设置的字符集和排序规则。 当出现如下信息,表示字符集设置成功。 Query OK, 0 rows affected (0.00 sec)
  • 原因分析 表字段类型是TIMESTAMP类型, 关于timestamp字段:MySQL会把该字段插入的值从当前时区转换成UTC时间(世界标准时间)存储,查询时,又将其从UTC时间转化为当前时区时间返回 timestamp类型字段的时间范围:'1970-01-01 00:00:01' UTC -- '2038-01-19 03:14:07' UTC,详见官方文档: 使用如下命令,查看当前的时区: show variables like "%zone%"; 故障场景中使用的是utc+8时区,如下图,所以timestamp字段默认值需要加8小时才是有效范围,有效支持的范围是从1970-01-01 08:00:01开始;
  • 原因分析 查看表结构发现存在JSON格式的大字段 create table `t1` ( `id` bigint not null, `num` int not null, `rank` int not null, `j1` json default null, `j2` json default null, `j3` json default null, primary key (`id`, `num`)) engine = InnoDB default charset = utf8 社区全字段排序特性导致该问题,对于BLOB/TEXT/JSON/GEOMETRY等大字段类型,虽然理论上最大可以达到4GB,但是在实际应用中基本不会达到这个数量级,如果只根据row IDs去做排序而不是完整的行,会导致需要二次回表去取数据,在这种场景下瓶颈就在回表上。因此如果开启了全字段排序,当sort_buffer_size比较小而行数据比较大,就会导致超过阈值报错。
  • 场景描述 执行以下查询报Out of sort memory,调大sort_buffer_size仍然报错,排查表数量较小 SELECT * FROM `t1` WHERE num = 4250 ORDER BY rank desc; 执行失败,失败原因:(conn=24259576) Out of sort memory, consider increasing server sort buffer size
  • 解决方案 为已有数据的表添加自增列时,请先创建相同表结构的新表,再在新表上添加自增列,将原表数据导入(导入数据时,请尽量保持原表无写入操作,否则会造成原表与新表数据不一致)。 按照如下步骤解决主备节点查询数据不一致问题。 在主节点上创建一个与无主键表(称之为原无主键表t1)相同的新表t2,并为新表中添加自增主键。 示例如下: CREATE TABLE t2 LIKE t1; ALTER TABLE t2 ADD id INT AUTO_INCREMENT PRIMARY KEY; 将原无主键表的数据全部插入到新表t2中。 示例如下: INSERT INTO t2(col1, col2) SELECT col1, col2 FROM t1 ORDER BY col1, col2; 为了确保主备节点对应表中数据的顺序相同,ORDER BY子句必须包含原无主键表的所有列。 删除原无主键表t1,并将新表重命名为原无主键表名。 示例如下: DROP TABLE t1; RENAME TABLE t2 TO t1;
  • 原因分析 查询确认,发现消失的账号在mysql.user表中已经被删除,因此在控制台不再显示。 使用账号名和旧密码还能连接登录,说明使用的是delete from mysql.user方式删除用户。使用这种方式删除用户,需要执行flush privileges后,才会清理内存中相关数据,该用户才彻底不能登录。 使用delete from mysql.user方式删除用户,无法重新创建相应账户(报错ERROR 1396),原因是内存中相关数据仍然存在。 正确删除用户的方式为drop user语句,注意以下几点: drop user语句可用于删除一个或多个用户,并撤销其权限。 使用drop user语句必须拥有MySQL数据库的DELETE权限或全局CREATE USER权限。 在drop user语句的使用中,若没有明确地给出账户的主机名,则该主机名默认为“%”。 故障场景恢复示例: 创建用户后用delete删除用户,再创建同名用户时报错ERROR 1396。通过执行flush privileges后,可正常创建同名用户。
  • 原因分析 在“innodb_large_prefix”设置为off的情况下,InnoDB表的单字段索引的最大字段长度不能超过767字节,联合索引的每个字段的长度不能超过767字节,且所有字段长度合计不能超过3072字节。 当“innodb_large_prefix”设置为on时,单字段索引最大长度可为3072字节,联合索引合计最大长度可为3072字节。 索引长度与字符集相关。使用utf8字符集时,一个字符占用三个字节,在“innodb_large_prefix”参数设置为on情况下,索引的所有字段的长度合计最大为1072个字符。 查看表结构如下: CREATE TABLE `xxxxx` (……`subscription_type` varchar(64) NOT NULL DEFAULT 'DEVICE_EXCEPTION' COMMENT '订阅类型',`auth_key` varchar(255) DEFAULT '' COMMENT '签名,接口请求头会根据这个值增加token',`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',PRIMARY KEY (`id`) USING BTREE,UNIQUE KEY `enterprise_id` (`subscription_type`,`enterprise_id`,`callback_url`) USING BTREE)) ENGINE=InnoDB AUTO_INCREMENT=1039 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC 该表使用了utf8字符集,一个字符占用三个字节。联合索引“enterprise_id”包含了“callback_url”字段,如果执行DDL操作将“callback_url”修改为varchar(1024),会超出联合索引最大长度限制,所以报错。