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!: "