0

Does the PDO lastinsertid function use MySQL's last_insert_id function?

I'm particularly interested in replication with AWS and per the AWS manual using some MySQL functions break replication:

Other common situations that can cause replication errors include the following:...Using unsafe nondeterministic queries

The mysql manual states that the functions I'm using aren't actually unsafe though:

Nondeterministic functions not considered unsafe

I plan to rewrite my now() usages but am not sure how I can avoid the last_insert_id since PDO, not I, am querying that. I can't do a separate select because it is likely an insert was run in parallel and I'll get back the wrong id.

4
  • 1
    Regarding how the PDO function is implemented, the source is here. It uses an internal function of the MySQL driver, mysql_insert_id, which reads a value already fetched during execution. So no extra call to MySQL is triggered, but I've no idea what the implications for replication are.
    – IMSoP
    Commented Sep 4, 2018 at 12:00
  • If you use binlog_format=ROW or even MIXED, then you won't have to worry about non-deterministic queries. Read dev.mysql.com/doc/refman/8.0/en/replication-formats.html Commented Sep 4, 2018 at 15:25
  • NOW() is safe even when you use statement-based replication. See the list of "not unsafe" (sic) functions here: dev.mysql.com/doc/refman/8.0/en/… Commented Sep 4, 2018 at 15:26
  • @BillKarwin I have binlog_format=ROW, mixed in the AWS instance. That broke the replication there. I have not had this issue when using standard mysql instances, I've used mixed in the past. Commented Sep 4, 2018 at 15:32

1 Answer 1

2

MySQL's LAST_INSERT_ID() function, the various bindings (like PDO's) and the underlying functionality are deterministic. You can use them with confidence.

For example this is deterministic and will work everywhere.

  INSERT INTO master (address, town) VALUES('150 Broadway', 'New York');
  INSERT INTO detail (master_id, item) VALUES (LAST_INSERT_ID(), 'pepperoni pizza');

This is not. This is the sort of thing you're warned against.

  INSERT INTO master (address, town) VALUES('150 Broadway', 'New York');
  SELECT @id := MAX(master_id) FROM master;   /* bad bad bad */
  INSERT INTO detail (master_id, item) VALUES (@id + 1 'pepperoni pizza');

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.