TiDB PDO::lastInsertId() 返回负数字符串

在TiDB环境中,PHP 7.2使用PDO连接并插入数据时,PDO::lastInsertId()返回负数字符串而非实际的正整数ID。问题源于PDO扩展在处理MySQL last_insert_id()返回值时,将无符号的uint64当作int64处理。通过源码分析,发现是PDO层的一个潜在bug。修复方案包括调整PDO源码或在业务层处理。此问题可能因TiDB使用不广泛和大多数单表数据不超过2^32而未引起广泛关注。
摘要由CSDN通过智能技术生成

PDO::lastInsertId() 返回负数字符串

参考文档:

MySQL 手册 last_insert_id() 方法
PHP PDO::lastInsertId()

背景及环境

  • TiDB 集群环境 tiup playgrand v4.0.0 --db 2 -pd 3 --kv 3 --monitor
  • PHP 版本 7.2
  • 使用 pdo_mysql 连接 TiDB
  • TIDB 表结构
create table foo (
	`id` bigint(20) unsigned auto_random(5),
	`name` varchar(20) not null default ''primary key(`id`)
);
// 没有接触过 TiDB 的同学也可以直接用 MySQL 建表测试
create table foo (
	`id` bigint(20) unsigned auto_increment,
	`name` varchar(20) not null default ''primary key(`id`)
) auto_increment=10376293541461622799;
/* 
* 注意:此处的 auto_increment 值已经超过 int64 的最大值 9223372036854775807,但是没有超过 uint64
*/

现象

使用PDO,连接MySQL,插入一行数据,获取 PDO::lastInsertId() 函数返回的是一个负数字符串。如:"-8646911284551352289",但实际表中的 id 为: 10376293541461622799,返回不符合预期。
TiDB 具备自动扩容分库分表的能力,插入一行数据之后,为了避免集群化带来的热点数据问题,会随机从 0 ~ 2^64 中取一个主键 ID 返回。

问题复现代码

try {
   
	$dbh = new PDO('mysql:host=docker.for.mac.localhost:4000', 'root', '');
	$dbb->exec("insert into foo (`name`) values ('bar')");
	echo $dbh->lastInsertId() . PHP_EOL;
} catch (PDOException $e) {
   
	print "Error!: " 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值