1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-27 12:41:57 +03:00

Support synchronization of snapshots through an export/import procedure.

A transaction can export a snapshot with pg_export_snapshot(), and then
others can import it with SET TRANSACTION SNAPSHOT.  The data does not
leave the server so there are not security issues.  A snapshot can only
be imported while the exporting transaction is still running, and there
are some other restrictions.

I'm not totally convinced that we've covered all the bases for SSI (true
serializable) mode, but it works fine for lesser isolation modes.

Joachim Wieland, reviewed by Marko Tiikkaja, and rather heavily modified
by Tom Lane
This commit is contained in:
Tom Lane
2011-10-22 18:22:45 -04:00
parent b436c72f61
commit bb446b689b
17 changed files with 1030 additions and 34 deletions

View File

@ -72,6 +72,7 @@
#include "utils/plancache.h"
#include "utils/portal.h"
#include "utils/ps_status.h"
#include "utils/snapmgr.h"
#include "utils/tzparser.h"
#include "utils/xml.h"
@ -6093,8 +6094,11 @@ ExecSetVariableStmt(VariableSetStmt *stmt)
case VAR_SET_MULTI:
/*
* Special case for special SQL syntax that effectively sets more
* than one variable per statement.
* Special-case SQL syntaxes. The TRANSACTION and SESSION
* CHARACTERISTICS cases effectively set more than one variable
* per statement. TRANSACTION SNAPSHOT only takes one argument,
* but we put it here anyway since it's a special case and not
* related to any GUC variable.
*/
if (strcmp(stmt->name, "TRANSACTION") == 0)
{
@ -6140,6 +6144,18 @@ ExecSetVariableStmt(VariableSetStmt *stmt)
item->defname);
}
}
else if (strcmp(stmt->name, "TRANSACTION SNAPSHOT") == 0)
{
A_Const *con = (A_Const *) linitial(stmt->args);
if (stmt->is_local)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("SET LOCAL TRANSACTION SNAPSHOT is not implemented")));
Assert(IsA(con, A_Const));
Assert(nodeTag(&con->val) == T_String);
ImportSnapshot(strVal(&con->val));
}
else
elog(ERROR, "unexpected SET MULTI element: %s",
stmt->name);