|
8 | 8 | * |
9 | 9 | * |
10 | 10 | * IDENTIFICATION |
11 | | - * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.593 2010/04/20 01:38:52 tgl Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.594 2010/05/12 19:45:02 sriggs Exp $ |
12 | 12 | * |
13 | 13 | * NOTES |
14 | 14 | * this is the "main" module of the postgres backend and |
@@ -174,6 +174,7 @@ static intUseNewLine = 0;/* Use EOF as query delimiters */ |
174 | 174 |
|
175 | 175 | /* whether or not, and why, we were cancelled by conflict with recovery */ |
176 | 176 | staticboolRecoveryConflictPending= false; |
| 177 | +staticboolRecoveryConflictRetryable= true; |
177 | 178 | staticProcSignalReasonRecoveryConflictReason; |
178 | 179 |
|
179 | 180 | /* ---------------------------------------------------------------- |
@@ -2836,6 +2837,15 @@ RecoveryConflictInterrupt(ProcSignalReason reason) |
2836 | 2837 |
|
2837 | 2838 | Assert(RecoveryConflictPending&& (QueryCancelPending||ProcDiePending)); |
2838 | 2839 |
|
| 2840 | +/* |
| 2841 | + * All conflicts apart from database cause dynamic errors where the |
| 2842 | + * command or transaction can be retried at a later point with some |
| 2843 | + * potential for success. No need to reset this, since |
| 2844 | + * non-retryable conflict errors are currently FATAL. |
| 2845 | + */ |
| 2846 | +if (reason==PROCSIG_RECOVERY_CONFLICT_DATABASE) |
| 2847 | +RecoveryConflictRetryable= false; |
| 2848 | + |
2839 | 2849 | /* |
2840 | 2850 | * If it's safe to interrupt, and we're waiting for input or a lock, |
2841 | 2851 | * service the interrupt immediately |
@@ -2885,6 +2895,11 @@ ProcessInterrupts(void) |
2885 | 2895 | ereport(FATAL, |
2886 | 2896 | (errcode(ERRCODE_ADMIN_SHUTDOWN), |
2887 | 2897 | errmsg("terminating autovacuum process due to administrator command"))); |
| 2898 | +elseif (RecoveryConflictPending&&RecoveryConflictRetryable) |
| 2899 | +ereport(FATAL, |
| 2900 | +(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), |
| 2901 | +errmsg("terminating connection due to conflict with recovery"), |
| 2902 | +errdetail_recovery_conflict())); |
2888 | 2903 | elseif (RecoveryConflictPending) |
2889 | 2904 | ereport(FATAL, |
2890 | 2905 | (errcode(ERRCODE_ADMIN_SHUTDOWN), |
@@ -2936,14 +2951,14 @@ ProcessInterrupts(void) |
2936 | 2951 | DisableCatchupInterrupt(); |
2937 | 2952 | if (DoingCommandRead) |
2938 | 2953 | ereport(FATAL, |
2939 | | -(errcode(ERRCODE_ADMIN_SHUTDOWN), |
| 2954 | +(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), |
2940 | 2955 | errmsg("terminating connection due to conflict with recovery"), |
2941 | 2956 | errdetail_recovery_conflict(), |
2942 | 2957 | errhint("In a moment you should be able to reconnect to the" |
2943 | 2958 | " database and repeat your command."))); |
2944 | 2959 | else |
2945 | 2960 | ereport(ERROR, |
2946 | | -(errcode(ERRCODE_QUERY_CANCELED), |
| 2961 | +(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), |
2947 | 2962 | errmsg("canceling statement due to conflict with recovery"), |
2948 | 2963 | errdetail_recovery_conflict())); |
2949 | 2964 | } |
|