项目场景:
项目使用TDSQL为系统的业务库,上线之后测试发现有一个接口查询视图数据时一直报错,报错内容:Prepared statement needs to be re-prepared 报表需要重新准备,检查发现查询的视图已创建,且sql语句放到navicat也是可以正常查询的,代码在测试环境可以正常运行并没有报错。通过分析,怀疑是数据库的问题。
问题描述
一个查询视图表的接口一直报错:
单独拿sql语句在数据库可以正常执行,并查到结果。
原因分析:
经过查阅帖子,有博主提到可能是数据库table_definition_cache 参数色设置问题导致。于是查询了当前数据库的一些参数:
#查询表高速缓存大小和高速缓存实例大小
SHOW VARIABLES LIKE ‘%table_open_cache%’;
#查询表定义文件默认缓存大小
SHOW VARIABLES LIKE ‘%table_definition_cache%’;
这里首先需要了解一下这两个参数的含义:
mysql官方问的文档:
https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_table_definition_cache
1.table_open_cache参数
table_open_cache是个全局参数,叫:查询表高速缓存大小,默认是2000,最小值1最大值524288,这是mysql服务器当前所有线程打开的表的数据量,增加这个值会增加mysql需要的文件描述符的数量。可以通过检查Opened_tables状态变量来检查是否需要增加表缓存。FLUSH TABLES命令会强迫所有的表去关闭然后重新打开。
2.table_definition_cache参数
table_definition_cache是全局参数,叫:查询表定义文件默认缓存大小。默认值为-1,最小是为400,描述的是.frm文件在定义换成里面存储的总量,如果你创建一个比较大的值,会加快你打开表的速度。这个表定义缓存会占据一些空间,它不同于常规的表缓存,它不会用文件描述符。
它的值最小400,一般依据下面的简单计算公式来估算:
table_definition_cache = (table_open_cache / 2) + 400
3.table_open_cache_instances参数
table_open_cache_instances高速缓存实例大小也是全局参数,默认16,最小1,最大64,打开的表缓存实例的数量。
通过分析,发现TDSQL 库的table_definition_cache 参数设置为400,该值过小,导致查询无法命中。测算一下:
table_definition_cache = (table_open_cache / 2) + 400 = (20480/2)+400 = 10640
所以需要设置:table_definition_cache >=10640
解决方案:
设置:table_definition_cache >=10640,我这里设置为:16384,命名如下:
mysql> set global table_definition_cache=16384;
设置完后,完美解决问题。以上仅供参考!