Re: TODO: Split out pg_resetxlog output into pre- and post-sections
On Sat, Nov 9, 2013, Amit Kapila wrote
On Fri, Nov 8, 2013 at 10:37 AM, Rajeev rastogi
<rajeev.rastogi@huawei.com<mailto:rajeev.rastogi@huawei.com>> wrote:
On Fri, 08 November 2013 09:47
On Tue, Nov 5, 2013 at 3:20 PM, Rajeev rastogi
<rajeev.rastogi@huawei.com<mailto:rajeev.rastogi@huawei.com>> wrote:
On execution of pg_resetxlog using the option -n
Please provide your opinion or expectation out of this patch.
Your approach in patch seems to be inline with Todo item. On a
quick glance, I observed few things which can make your patch better:
1. The purpose was to print pg_control values in one section and
any other reset values in different section, so in that
regard, should we display below in new section, as here
newXlogSegNo is not directly from pg_control.
PrintControlValues()
{
..
XLogFileName(fname, ControlFile.checkPointCopy.ThisTimeLineID,
newXlogSegNo);
printf(_("First log segment after reset: %s\n"),
fname);
}
Yes we can print newXlogSegNo.
I think then your documentation also need updates.
I have added to documentation.
One more thing, I think as per this patch few parameters will be
displayed twice once in "pg_control values .." section and once in
"Values to be used after reset:", so by doing this I guess you want to
make it easier for user to refer both pg_control's original/guessed
value and new value after reset. Here I wonder if someone wants to
refer to original values, can't he directly use pg_controldata? Anyone
else have thoughts about how can we display values which can make
current situation better for user.
Aim of this patch is to:
1. Without this patch, if I give some parameter using -l switch and also provide -n switch
Then it will display this values as "TimeLineID of latest checkpoint", which is not
Really the truth.
1. So we can print both actual values and values to be used after reset in different section
So that is extra clear.
Usage of pg_controldata may not be preferable in this case because:
1. User will have to use two separate executable, which can be actually achieved by only pg_resetxlog.
2. pg_controldata prints many other additional parameters, in which user may not be interested.
I have attached the updated patch.
Please let me know if it is OK or anyone else have any other idea.
Note: Replied this mail on 11th Nov also but for some reason didn't appear in community mail chain.
Thanks and Regards,
Kumar Rajeev Rastogi
Attachments:
pg_resetxlogsectionV2.patchapplication/octet-stream; name=pg_resetxlogsectionV2.patchDownload
*** a/doc/src/sgml/ref/pg_resetxlog.sgml
--- b/doc/src/sgml/ref/pg_resetxlog.sgml
***************
*** 180,185 **** PostgreSQL documentation
--- 180,189 ----
<filename>pg_control</> and then exit without modifying anything.
This is mainly a debugging tool, but can be useful as a sanity check
before allowing <command>pg_resetxlog</command> to proceed for real.
+ It will print values in two sections. In first section it will print all original/guessed values
+ and in second section all values to be used after reset. In second section segment
+ number and file ID will be always printed and if any other parameter is given using
+ appropriate switch, then those new values will be also printed.
</para>
<para>
*** a/src/bin/pg_resetxlog/pg_resetxlog.c
--- b/src/bin/pg_resetxlog/pg_resetxlog.c
***************
*** 56,61 ****
--- 56,69 ----
#include "catalog/pg_control.h"
#include "common/fe_memutils.h"
+ /* Indicate which control file parameter going to be changed*/
+ #define DISPLAY_XIDEPOCH 1
+ #define DISPLAY_XLOGFILE 2
+ #define DISPLAY_MXID 4
+ #define DISPLAY_OID 8
+ #define DISPLAY_OFFSET 16
+ #define DISPLAY_XID 32
+
extern int optind;
extern char *optarg;
***************
*** 68,73 **** static const char *progname;
--- 76,82 ----
static bool ReadControlFile(void);
static void GuessControlValues(void);
static void PrintControlValues(bool guessed);
+ static void PrintNewControlValues(int changedParam);
static void RewriteControlFile(void);
static void FindEndOfXLOG(void);
static void KillExistingXLOG(void);
***************
*** 94,99 **** main(int argc, char *argv[])
--- 103,109 ----
char *endptr2;
char *DataDir;
int fd;
+ int changedParam = 0;
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_resetxlog"));
***************
*** 128,133 **** main(int argc, char *argv[])
--- 138,144 ----
case 'e':
set_xid_epoch = strtoul(optarg, &endptr, 0);
+ changedParam |= DISPLAY_XIDEPOCH;
if (endptr == optarg || *endptr != '\0')
{
fprintf(stderr, _("%s: invalid argument for option -e\n"), progname);
***************
*** 143,148 **** main(int argc, char *argv[])
--- 154,160 ----
case 'x':
set_xid = strtoul(optarg, &endptr, 0);
+ changedParam |= DISPLAY_XID;
if (endptr == optarg || *endptr != '\0')
{
fprintf(stderr, _("%s: invalid argument for option -x\n"), progname);
***************
*** 158,163 **** main(int argc, char *argv[])
--- 170,176 ----
case 'o':
set_oid = strtoul(optarg, &endptr, 0);
+ changedParam |= DISPLAY_OID;
if (endptr == optarg || *endptr != '\0')
{
fprintf(stderr, _("%s: invalid argument for option -o\n"), progname);
***************
*** 173,178 **** main(int argc, char *argv[])
--- 186,192 ----
case 'm':
set_mxid = strtoul(optarg, &endptr, 0);
+ changedParam |= DISPLAY_MXID;
if (endptr == optarg || *endptr != ',')
{
fprintf(stderr, _("%s: invalid argument for option -m\n"), progname);
***************
*** 207,212 **** main(int argc, char *argv[])
--- 221,227 ----
case 'O':
set_mxoff = strtoul(optarg, &endptr, 0);
+ changedParam |= DISPLAY_OFFSET;
if (endptr == optarg || *endptr != '\0')
{
fprintf(stderr, _("%s: invalid argument for option -O\n"), progname);
***************
*** 228,233 **** main(int argc, char *argv[])
--- 243,249 ----
exit(1);
}
XLogFromFileName(optarg, &minXlogTli, &minXlogSegNo);
+ changedParam |= DISPLAY_XLOGFILE;
break;
default:
***************
*** 301,306 **** main(int argc, char *argv[])
--- 317,326 ----
*/
FindEndOfXLOG();
+ /* print current control file parameter value if -n is given*/
+ if (noupdate)
+ PrintControlValues(guessed);
+
/*
* Adjust fields if required by switches. (Do this now so that printout,
* if any, includes these values.)
***************
*** 350,360 **** main(int argc, char *argv[])
if (minXlogSegNo > newXlogSegNo)
newXlogSegNo = minXlogSegNo;
/*
* If we had to guess anything, and -f was not given, just print the
! * guessed values and exit. Also print if -n is given.
*/
! if ((guessed && !force) || noupdate)
{
PrintControlValues(guessed);
if (!noupdate)
--- 370,387 ----
if (minXlogSegNo > newXlogSegNo)
newXlogSegNo = minXlogSegNo;
+ /* Print only new values to be reset if -n is given*/
+ if (noupdate)
+ {
+ PrintNewControlValues(changedParam);
+ exit(0);
+ }
+
/*
* If we had to guess anything, and -f was not given, just print the
! * guessed values and exit.
*/
! if (guessed && !force)
{
PrintControlValues(guessed);
if (!noupdate)
***************
*** 561,567 **** PrintControlValues(bool guessed)
if (guessed)
printf(_("Guessed pg_control values:\n\n"));
else
! printf(_("pg_control values:\n\n"));
/*
* Format system_identifier separately to keep platform-dependent format
--- 588,594 ----
if (guessed)
printf(_("Guessed pg_control values:\n\n"));
else
! printf(_("Current pg_control values:\n\n"));
/*
* Format system_identifier separately to keep platform-dependent format
***************
*** 631,636 **** PrintControlValues(bool guessed)
--- 658,723 ----
}
+ /*
+ * Print the values to be changed after pg_resetxlog.
+ *
+ * NB: this display should be just for those fields that are
+ * going to change after reset.
+ */
+ static void
+ PrintNewControlValues(int changedParam)
+ {
+
+ printf(_("\n\nValues to be used after reset:\n\n"));
+
+ /* newXlogSegNo will be always printed unconditionally*/
+ printf(_("First log file ID: %u\n"),
+ (uint32) ((newXlogSegNo) / XLogSegmentsPerXLogId));
+ printf(_("First log file segment: %u\n"),
+ (uint32) ((newXlogSegNo) % XLogSegmentsPerXLogId));
+
+ if (changedParam & DISPLAY_XLOGFILE)
+ {
+ printf(_("TimeLineID: %u\n"),
+ ControlFile.checkPointCopy.ThisTimeLineID);
+ }
+
+ if (changedParam & DISPLAY_MXID)
+ {
+ printf(_("NextMultiXactId: %u\n"),
+ ControlFile.checkPointCopy.nextMulti);
+ printf(_("oldestMultiXid: %u\n"),
+ ControlFile.checkPointCopy.oldestMulti);
+ }
+
+ if (changedParam & DISPLAY_OFFSET)
+ {
+ printf(_("NextMultiOffset: %u\n"),
+ ControlFile.checkPointCopy.nextMultiOffset);
+ }
+
+ if (changedParam & DISPLAY_OID)
+ {
+ printf(_("NextOID: %u\n"),
+ ControlFile.checkPointCopy.nextOid);
+ }
+
+ if (changedParam & DISPLAY_XID)
+ {
+ printf(_("NextXID: %u\n"),
+ ControlFile.checkPointCopy.nextXid);
+ printf(_("oldestXID: %u\n"),
+ ControlFile.checkPointCopy.oldestXid);
+ }
+
+ if (changedParam & DISPLAY_XIDEPOCH)
+ {
+ printf(_("NextXID Epoch: %u\n"),
+ ControlFile.checkPointCopy.nextXidEpoch);
+ }
+ }
+
+
/*
* Write out the new pg_control file.
*/
***************
*** 1039,1045 **** usage(void)
printf(_(" -f force update to be done\n"));
printf(_(" -l XLOGFILE force minimum WAL starting location for new transaction log\n"));
printf(_(" -m MXID,MXID set next and oldest multitransaction ID\n"));
! printf(_(" -n no update, just show extracted control values (for testing)\n"));
printf(_(" -o OID set next OID\n"));
printf(_(" -O OFFSET set next multitransaction offset\n"));
printf(_(" -V, --version output version information, then exit\n"));
--- 1126,1132 ----
printf(_(" -f force update to be done\n"));
printf(_(" -l XLOGFILE force minimum WAL starting location for new transaction log\n"));
printf(_(" -m MXID,MXID set next and oldest multitransaction ID\n"));
! printf(_(" -n no update, just show extracted control values (for testing) and to be reset values of parameters(if given)\n"));
printf(_(" -o OID set next OID\n"));
printf(_(" -O OFFSET set next multitransaction offset\n"));
printf(_(" -V, --version output version information, then exit\n"));
On Mon, Nov 25, 2013 at 9:17 AM, Rajeev rastogi
<rajeev.rastogi@huawei.com> wrote:
On Sat, Nov 9, 2013, Amit Kapila wrote
Further Review of this patch:
a. there are lot of trailing whitespaces in patch.
b. why to display 'First log segment after reset' in 'Currrent
pg_control values' section as now the same information
is available in new section "Values to be used after reset:" ?
c. I think it is better to display 'First log segment after reset' as
file name as it was earlier.
This utility takes filename as input, so I think we should display filename.
d. I still think it is not good idea to use new parameter changedParam
to detect which parameters are changed and the reason is
code already has that information. We should try to use that
information rather introducing new parameter to mean the same.
e.
if (guessed && !force)
{
PrintControlValues(guessed);
if (!noupdate)
{
printf(_("\nIf these values seem acceptable, use -f to force reset.\n"));
exit(1);
}
Do you think there will be any chance when noupdate can be true in
above loop, if not then why to keep the check for same?
f.
if (changedParam & DISPLAY_XID)
{
printf(_("NextXID: %u\n"),
ControlFile.checkPointCopy.nextXid);
printf(_("oldestXID: %u\n"),
ControlFile.checkPointCopy.oldestXid);
}
Here you are priniting oldestXid, but not oldestXidDB, if user
provides xid both values are changed. Same is the case
for multitransaction.
g.
/* newXlogSegNo will be always printed unconditionally*/
Extra space between always and printed. In single line comments space
should be provided when comment text ends, please refer
other single line comments.
In case when the values are guessed and -n option is not given, then
this patch will not be able to distinguish the values. Don't you think
it is better to display values in 2 sections in case of guessed values
without -n flag as well, otherwise this utility will have 2 format's
to display values?
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 26 November 2013, Amit Kapila Wrote:
Further Review of this patch:
a. there are lot of trailing whitespaces in patch.
Fixed.
b. why to display 'First log segment after reset' in 'Currrent
pg_control values' section as now the same information
is available in new section "Values to be used after reset:" ?
May not be always. Suppose if user has given new value of seg no and TLI, then it will be different.
Otherwise it will be same.
So now I have changed the code in such way that the value of XLOG segment # read from
checkpoint record gets printed as part of current value and any further new value gets
printed in Values to be reset (This will be always at-least one plus the current value). Because
of following code in FindEndOfXLOG
xlogbytepos = newXlogSegNo * ControlFile.xlog_seg_size;
newXlogSegNo = (xlogbytepos + XLogSegSize - 1) / XLogSegSize;
newXlogSegNo++;
c. I think it is better to display 'First log segment after reset' as
file name as it was earlier.
This utility takes filename as input, so I think we should display
filename.
Fixed. Printing filename.
d. I still think it is not good idea to use new parameter changedParam
to detect which parameters are changed and the reason is
code already has that information. We should try to use that
information rather introducing new parameter to mean the same.
Fixed. Removed changedParam and made existing variables like set_xid
global and same is being used for check.
e.
if (guessed && !force)
{
PrintControlValues(guessed);
if (!noupdate)
{
printf(_("\nIf these values seem acceptable, use -f to force
reset.\n")); exit(1); }Do you think there will be any chance when noupdate can be true in
above loop, if not then why to keep the check for same?
Fixed along with the last comment.
f.
if (changedParam & DISPLAY_XID)
{
printf(_("NextXID: %u\n"),
ControlFile.checkPointCopy.nextXid);
printf(_("oldestXID: %u\n"),
ControlFile.checkPointCopy.oldestXid);
}
Here you are priniting oldestXid, but not oldestXidDB, if user provides
xid both values are changed. Same is the case for multitransaction.
Fixed.
g.
/* newXlogSegNo will be always printed unconditionally*/ Extra space
between always and printed. In single line comments space should be
provided when comment text ends, please refer other single line
comments.
Fixed.
In case when the values are guessed and -n option is not given, then
this patch will not be able to distinguish the values. Don't you think
it is better to display values in 2 sections in case of guessed values
without -n flag as well, otherwise this utility will have 2 format's to
display values?
Yes you are right. Now printing the values in two section in two cases:
a. -n is given or
b. If we had to guess and -f not given.
Please let know your opinion.
Thanks and Regards,
Kumar Rajeev Rastogi
Attachments:
pg_resetxlogsectionV3.patchapplication/octet-stream; name=pg_resetxlogsectionV3.patchDownload
*** a/doc/src/sgml/ref/pg_resetxlog.sgml
--- b/doc/src/sgml/ref/pg_resetxlog.sgml
***************
*** 180,185 **** PostgreSQL documentation
--- 180,189 ----
<filename>pg_control</> and then exit without modifying anything.
This is mainly a debugging tool, but can be useful as a sanity check
before allowing <command>pg_resetxlog</command> to proceed for real.
+ It will print values in two sections. In first section it will print all original/guessed values
+ and in second section all values to be used after reset. In second section filename will be
+ always printed as segment number will be at-least one more than current. Also if any other parameter
+ is given using appropriate switch, then those new values will be also printed.
</para>
<para>
*** a/src/bin/pg_resetxlog/pg_resetxlog.c
--- b/src/bin/pg_resetxlog/pg_resetxlog.c
***************
*** 65,73 **** static XLogSegNo newXlogSegNo; /* new XLOG segment # */
--- 65,83 ----
static bool guessed = false; /* T if we had to guess at any values */
static const char *progname;
+ static uint32 set_xid_epoch = (uint32) -1;
+ static TransactionId set_xid = 0;
+ static Oid set_oid = 0;
+ static MultiXactId set_mxid = 0;
+ static MultiXactOffset set_mxoff = (MultiXactOffset) -1;
+ static uint32 minXlogTli = 0;
+ static XLogSegNo minXlogSegNo = 0;
+ static XLogSegNo currentXlogSegNo = 0; /* current segment # from checkpoint */
+
static bool ReadControlFile(void);
static void GuessControlValues(void);
static void PrintControlValues(bool guessed);
+ static void PrintNewControlValues(void);
static void RewriteControlFile(void);
static void FindEndOfXLOG(void);
static void KillExistingXLOG(void);
***************
*** 82,95 **** main(int argc, char *argv[])
int c;
bool force = false;
bool noupdate = false;
- uint32 set_xid_epoch = (uint32) -1;
- TransactionId set_xid = 0;
- Oid set_oid = 0;
- MultiXactId set_mxid = 0;
MultiXactId set_oldestmxid = 0;
- MultiXactOffset set_mxoff = (MultiXactOffset) -1;
- uint32 minXlogTli = 0;
- XLogSegNo minXlogSegNo = 0;
char *endptr;
char *endptr2;
char *DataDir;
--- 92,98 ----
***************
*** 302,307 **** main(int argc, char *argv[])
--- 305,317 ----
FindEndOfXLOG();
/*
+ * Print current control file parameters, if had to guess anything and -f
+ * was not given or -n is given.
+ */
+ if ((guessed && !force) || noupdate)
+ PrintControlValues(guessed);
+
+ /*
* Adjust fields if required by switches. (Do this now so that printout,
* if any, includes these values.)
*/
***************
*** 352,362 **** main(int argc, char *argv[])
/*
* If we had to guess anything, and -f was not given, just print the
! * guessed values and exit. Also print if -n is given.
*/
if ((guessed && !force) || noupdate)
{
! PrintControlValues(guessed);
if (!noupdate)
{
printf(_("\nIf these values seem acceptable, use -f to force reset.\n"));
--- 362,372 ----
/*
* If we had to guess anything, and -f was not given, just print the
! * values to be reset and exit. Also print value to be reset if -n is given.
*/
if ((guessed && !force) || noupdate)
{
! PrintNewControlValues();
if (!noupdate)
{
printf(_("\nIf these values seem acceptable, use -f to force reset.\n"));
***************
*** 561,567 **** PrintControlValues(bool guessed)
if (guessed)
printf(_("Guessed pg_control values:\n\n"));
else
! printf(_("pg_control values:\n\n"));
/*
* Format system_identifier separately to keep platform-dependent format
--- 571,577 ----
if (guessed)
printf(_("Guessed pg_control values:\n\n"));
else
! printf(_("Current pg_control values:\n\n"));
/*
* Format system_identifier separately to keep platform-dependent format
***************
*** 570,576 **** PrintControlValues(bool guessed)
snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
ControlFile.system_identifier);
! XLogFileName(fname, ControlFile.checkPointCopy.ThisTimeLineID, newXlogSegNo);
printf(_("First log segment after reset: %s\n"),
fname);
--- 580,586 ----
snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
ControlFile.system_identifier);
! XLogFileName(fname, ControlFile.checkPointCopy.ThisTimeLineID, currentXlogSegNo);
printf(_("First log segment after reset: %s\n"),
fname);
***************
*** 632,637 **** PrintControlValues(bool guessed)
--- 642,704 ----
/*
+ * Print the values to be changed after pg_resetxlog.
+ *
+ * NB: this display should be just for those fields that are
+ * going to change after reset.
+ */
+ static void
+ PrintNewControlValues()
+ {
+ char fname[MAXFNAMELEN];
+
+ /* This will be always printed in order to keep format same. */
+ printf(_("\n\nValues to be used after reset:\n\n"));
+
+ XLogFileName(fname, ControlFile.checkPointCopy.ThisTimeLineID, newXlogSegNo);
+ printf(_("First log segment after reset: %s\n"), fname);
+
+ if (set_mxid != 0)
+ {
+ printf(_("NextMultiXactId: %u\n"),
+ ControlFile.checkPointCopy.nextMulti);
+ printf(_("OldestMultiXid: %u\n"),
+ ControlFile.checkPointCopy.oldestMulti);
+ printf(_("OldestMulti's DB: %u\n"),
+ ControlFile.checkPointCopy.oldestMultiDB);
+ }
+
+ if (set_mxoff != -1)
+ {
+ printf(_("NextMultiOffset: %u\n"),
+ ControlFile.checkPointCopy.nextMultiOffset);
+ }
+
+ if (set_oid != 0)
+ {
+ printf(_("NextOID: %u\n"),
+ ControlFile.checkPointCopy.nextOid);
+ }
+
+ if (set_xid != 0)
+ {
+ printf(_("NextXID: %u\n"),
+ ControlFile.checkPointCopy.nextXid);
+ printf(_("OldestXID: %u\n"),
+ ControlFile.checkPointCopy.oldestXid);
+ printf(_("OldestXID's DB: %u\n"),
+ ControlFile.checkPointCopy.oldestXidDB);
+ }
+
+ if (set_xid_epoch != -1)
+ {
+ printf(_("NextXID Epoch: %u\n"),
+ ControlFile.checkPointCopy.nextXidEpoch);
+ }
+ }
+
+
+ /*
* Write out the new pg_control file.
*/
static void
***************
*** 753,758 **** FindEndOfXLOG(void)
--- 820,826 ----
*/
segs_per_xlogid = (UINT64CONST(0x0000000100000000) / ControlFile.xlog_seg_size);
newXlogSegNo = ControlFile.checkPointCopy.redo / ControlFile.xlog_seg_size;
+ currentXlogSegNo = newXlogSegNo;
/*
* Scan the pg_xlog directory to find existing WAL segment files. We
***************
*** 1039,1045 **** usage(void)
printf(_(" -f force update to be done\n"));
printf(_(" -l XLOGFILE force minimum WAL starting location for new transaction log\n"));
printf(_(" -m MXID,MXID set next and oldest multitransaction ID\n"));
! printf(_(" -n no update, just show extracted control values (for testing)\n"));
printf(_(" -o OID set next OID\n"));
printf(_(" -O OFFSET set next multitransaction offset\n"));
printf(_(" -V, --version output version information, then exit\n"));
--- 1107,1113 ----
printf(_(" -f force update to be done\n"));
printf(_(" -l XLOGFILE force minimum WAL starting location for new transaction log\n"));
printf(_(" -m MXID,MXID set next and oldest multitransaction ID\n"));
! printf(_(" -n no update, just show extracted control values (for testing) and to be reset values of parameters(if given)\n"));
printf(_(" -o OID set next OID\n"));
printf(_(" -O OFFSET set next multitransaction offset\n"));
printf(_(" -V, --version output version information, then exit\n"));
On Tue, Nov 26, 2013 at 5:33 PM, Rajeev rastogi
<rajeev.rastogi@huawei.com> wrote:
On 26 November 2013, Amit Kapila Wrote:
Further Review of this patch:
b. why to display 'First log segment after reset' in 'Currrent
pg_control values' section as now the same information
is available in new section "Values to be used after reset:" ?May not be always. Suppose if user has given new value of seg no and TLI, then it will be different.
Otherwise it will be same.
So now I have changed the code in such way that the value of XLOG segment # read from
checkpoint record gets printed as part of current value and any further new value gets
printed in Values to be reset (This will be always at-least one plus the current value). Because
of following code in FindEndOfXLOG
xlogbytepos = newXlogSegNo * ControlFile.xlog_seg_size;
newXlogSegNo = (xlogbytepos + XLogSegSize - 1) / XLogSegSize;
newXlogSegNo++;
It can be different, but I don't think we should display it in both
sections because:
a. it doesn't belong to control file.
b. if you carefully look at original link
(/messages/by-id/1283277511-sup-2152@alvh.no-ip.org),
these values are not getting displayed in pg_control values section.
So I suggest it is better to remove it from pg_control values section.
Few new comments:
1.
Formatting for 'OldestMulti's DB' and 'OldestXID's DB' is not
consistent with other values, try by printing it.
2.
+ It will print values in two sections. In first section it will
print all original/guessed values
+ and in second section all values to be used after reset. In
second section filename will be
+ always printed as segment number will be at-least one more than
current. Also if any other parameter
+ is given using appropriate switch, then those new values will be
also printed.
a. the length of newly added lines is not in sync with previous text,
try to keep length less than 80 chars.
b. I think there is no need of text (In second section ....), you can
remove all text after that point.
3.
! printf(_(" -n no update, just show extracted control
values (for testing) and to be reset values of parameters(if
given)\n"));
I find this line too long and elaborative, try to make it shorter.
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 28 November 2013, Amit Kapila Wrote:
Further Review of this patch:
b. why to display 'First log segment after reset' in 'Currrent
pg_control values' section as now the same information
is available in new section "Values to be used after reset:" ?May not be always. Suppose if user has given new value of seg no and
TLI, then it will be different.
Otherwise it will be same.
So now I have changed the code in such way that the value of XLOG
segment # read from checkpoint record gets printed as part of current
value and any further new value gets printed in Values to be reset
(This will be always at-least one plus the current value). Because offollowing code in FindEndOfXLOG
xlogbytepos = newXlogSegNo *
ControlFile.xlog_seg_size;
newXlogSegNo = (xlogbytepos + XLogSegSize - 1)
/ XLogSegSize;
newXlogSegNo++;
It can be different, but I don't think we should display it in both
sections because:
a. it doesn't belong to control file.
b. if you carefully look at original link
(/messages/by-id/1283277511-sup-2152@alvh.no-
ip.org),
these values are not getting displayed in pg_control values section.So I suggest it is better to remove it from pg_control values section.
Done as per suggestion.
Few new comments:
1.
Formatting for 'OldestMulti's DB' and 'OldestXID's DB' is not
consistent with other values, try by printing it.
Changed to align output.
2. + It will print values in two sections. In first section it will print all original/guessed values + and in second section all values to be used after reset. In second section filename will be + always printed as segment number will be at-least one more than current. Also if any other parameter + is given using appropriate switch, then those new values will be also printed.a. the length of newly added lines is not in sync with previous text,
try to keep length less than 80 chars.
b. I think there is no need of text (In second section ....), you can
remove all text after that point.
Done.
3.
! printf(_(" -n no update, just show extracted control
values (for testing) and to be reset values of parameters(if
given)\n")); I find this line too long and elaborative, try to make it
shorter.
Changed accordingly.
Please provide your opinion.
Thanks and Regards,
Kumar Rajeev Rastogi
Attachments:
pg_resetxlogsectionV4.patchapplication/octet-stream; name=pg_resetxlogsectionV4.patchDownload
*** a/doc/src/sgml/ref/pg_resetxlog.sgml
--- b/doc/src/sgml/ref/pg_resetxlog.sgml
***************
*** 180,185 **** PostgreSQL documentation
--- 180,188 ----
<filename>pg_control</> and then exit without modifying anything.
This is mainly a debugging tool, but can be useful as a sanity check
before allowing <command>pg_resetxlog</command> to proceed for real.
+ It will print values in two sections. In first section it will print
+ all original/guessed values and in second section all values to be
+ used after reset.
</para>
<para>
*** a/src/bin/pg_resetxlog/pg_resetxlog.c
--- b/src/bin/pg_resetxlog/pg_resetxlog.c
***************
*** 65,73 **** static XLogSegNo newXlogSegNo; /* new XLOG segment # */
--- 65,82 ----
static bool guessed = false; /* T if we had to guess at any values */
static const char *progname;
+ static uint32 set_xid_epoch = (uint32) -1;
+ static TransactionId set_xid = 0;
+ static Oid set_oid = 0;
+ static MultiXactId set_mxid = 0;
+ static MultiXactOffset set_mxoff = (MultiXactOffset) -1;
+ static uint32 minXlogTli = 0;
+ static XLogSegNo minXlogSegNo = 0;
+
static bool ReadControlFile(void);
static void GuessControlValues(void);
static void PrintControlValues(bool guessed);
+ static void PrintNewControlValues(void);
static void RewriteControlFile(void);
static void FindEndOfXLOG(void);
static void KillExistingXLOG(void);
***************
*** 82,95 **** main(int argc, char *argv[])
int c;
bool force = false;
bool noupdate = false;
- uint32 set_xid_epoch = (uint32) -1;
- TransactionId set_xid = 0;
- Oid set_oid = 0;
- MultiXactId set_mxid = 0;
MultiXactId set_oldestmxid = 0;
- MultiXactOffset set_mxoff = (MultiXactOffset) -1;
- uint32 minXlogTli = 0;
- XLogSegNo minXlogSegNo = 0;
char *endptr;
char *endptr2;
char *DataDir;
--- 91,97 ----
***************
*** 302,307 **** main(int argc, char *argv[])
--- 304,316 ----
FindEndOfXLOG();
/*
+ * Print current control file parameters, if had to guess anything and -f
+ * was not given or -n is given.
+ */
+ if ((guessed && !force) || noupdate)
+ PrintControlValues(guessed);
+
+ /*
* Adjust fields if required by switches. (Do this now so that printout,
* if any, includes these values.)
*/
***************
*** 352,362 **** main(int argc, char *argv[])
/*
* If we had to guess anything, and -f was not given, just print the
! * guessed values and exit. Also print if -n is given.
*/
if ((guessed && !force) || noupdate)
{
! PrintControlValues(guessed);
if (!noupdate)
{
printf(_("\nIf these values seem acceptable, use -f to force reset.\n"));
--- 361,372 ----
/*
* If we had to guess anything, and -f was not given, just print the
! * values to be reset and exit. Also print value to be reset if -n is
! * given.
*/
if ((guessed && !force) || noupdate)
{
! PrintNewControlValues();
if (!noupdate)
{
printf(_("\nIf these values seem acceptable, use -f to force reset.\n"));
***************
*** 556,567 **** static void
PrintControlValues(bool guessed)
{
char sysident_str[32];
- char fname[MAXFNAMELEN];
if (guessed)
printf(_("Guessed pg_control values:\n\n"));
else
! printf(_("pg_control values:\n\n"));
/*
* Format system_identifier separately to keep platform-dependent format
--- 566,576 ----
PrintControlValues(bool guessed)
{
char sysident_str[32];
if (guessed)
printf(_("Guessed pg_control values:\n\n"));
else
! printf(_("Current pg_control values:\n\n"));
/*
* Format system_identifier separately to keep platform-dependent format
***************
*** 570,579 **** PrintControlValues(bool guessed)
snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
ControlFile.system_identifier);
- XLogFileName(fname, ControlFile.checkPointCopy.ThisTimeLineID, newXlogSegNo);
-
- printf(_("First log segment after reset: %s\n"),
- fname);
printf(_("pg_control version number: %u\n"),
ControlFile.pg_control_version);
printf(_("Catalog version number: %u\n"),
--- 579,584 ----
***************
*** 632,637 **** PrintControlValues(bool guessed)
--- 637,699 ----
/*
+ * Print the values to be changed after pg_resetxlog.
+ *
+ * NB: this display should be just for those fields that are
+ * going to change after reset.
+ */
+ static void
+ PrintNewControlValues()
+ {
+ char fname[MAXFNAMELEN];
+
+ /* This will be always printed in order to keep format same. */
+ printf(_("\n\nValues to be used after reset:\n\n"));
+
+ XLogFileName(fname, ControlFile.checkPointCopy.ThisTimeLineID, newXlogSegNo);
+ printf(_("First log segment after reset: %s\n"), fname);
+
+ if (set_mxid != 0)
+ {
+ printf(_("NextMultiXactId: %u\n"),
+ ControlFile.checkPointCopy.nextMulti);
+ printf(_("OldestMultiXid: %u\n"),
+ ControlFile.checkPointCopy.oldestMulti);
+ printf(_("OldestMulti's DB: %u\n"),
+ ControlFile.checkPointCopy.oldestMultiDB);
+ }
+
+ if (set_mxoff != -1)
+ {
+ printf(_("NextMultiOffset: %u\n"),
+ ControlFile.checkPointCopy.nextMultiOffset);
+ }
+
+ if (set_oid != 0)
+ {
+ printf(_("NextOID: %u\n"),
+ ControlFile.checkPointCopy.nextOid);
+ }
+
+ if (set_xid != 0)
+ {
+ printf(_("NextXID: %u\n"),
+ ControlFile.checkPointCopy.nextXid);
+ printf(_("OldestXID: %u\n"),
+ ControlFile.checkPointCopy.oldestXid);
+ printf(_("OldestXID's DB: %u\n"),
+ ControlFile.checkPointCopy.oldestXidDB);
+ }
+
+ if (set_xid_epoch != -1)
+ {
+ printf(_("NextXID Epoch: %u\n"),
+ ControlFile.checkPointCopy.nextXidEpoch);
+ }
+ }
+
+
+ /*
* Write out the new pg_control file.
*/
static void
***************
*** 1039,1045 **** usage(void)
printf(_(" -f force update to be done\n"));
printf(_(" -l XLOGFILE force minimum WAL starting location for new transaction log\n"));
printf(_(" -m MXID,MXID set next and oldest multitransaction ID\n"));
! printf(_(" -n no update, just show extracted control values (for testing)\n"));
printf(_(" -o OID set next OID\n"));
printf(_(" -O OFFSET set next multitransaction offset\n"));
printf(_(" -V, --version output version information, then exit\n"));
--- 1101,1107 ----
printf(_(" -f force update to be done\n"));
printf(_(" -l XLOGFILE force minimum WAL starting location for new transaction log\n"));
printf(_(" -m MXID,MXID set next and oldest multitransaction ID\n"));
! printf(_(" -n no update, just show extracted and to be reset control values.\n"));
printf(_(" -o OID set next OID\n"));
printf(_(" -O OFFSET set next multitransaction offset\n"));
printf(_(" -V, --version output version information, then exit\n"));
On Thu, Nov 28, 2013 at 12:11 PM, Rajeev rastogi
<rajeev.rastogi@huawei.com> wrote:
On 28 November 2013, Amit Kapila Wrote:
Further Review of this patch:
b. why to display 'First log segment after reset' in 'Currrent
pg_control values' section as now the same information
is available in new section "Values to be used after reset:" ?May not be always. Suppose if user has given new value of seg no and
TLI, then it will be different.
Otherwise it will be same.
So now I have changed the code in such way that the value of XLOG
segment # read from checkpoint record gets printed as part of current
value and any further new value gets printed in Values to be reset
(This will be always at-least one plus the current value). Because offollowing code in FindEndOfXLOG
xlogbytepos = newXlogSegNo *
ControlFile.xlog_seg_size;
newXlogSegNo = (xlogbytepos + XLogSegSize - 1)
/ XLogSegSize;
newXlogSegNo++;
It can be different, but I don't think we should display it in both
sections because:
a. it doesn't belong to control file.
b. if you carefully look at original link
(/messages/by-id/1283277511-sup-2152@alvh.no-
ip.org),
these values are not getting displayed in pg_control values section.So I suggest it is better to remove it from pg_control values section.
Done as per suggestion.
I have done few more cosmetic changes in your patch, please find the
updated patch attached with this mail.
Kindly check once whether changes are okay.
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com
Attachments:
pg_resetxlogsectionV5.patchapplication/octet-stream; name=pg_resetxlogsectionV5.patchDownload
diff --git a/doc/src/sgml/ref/pg_resetxlog.sgml b/doc/src/sgml/ref/pg_resetxlog.sgml
index c680680..f7876d0 100644
--- a/doc/src/sgml/ref/pg_resetxlog.sgml
+++ b/doc/src/sgml/ref/pg_resetxlog.sgml
@@ -177,9 +177,10 @@ PostgreSQL documentation
<para>
The <option>-n</> (no operation) option instructs
<command>pg_resetxlog</command> to print the values reconstructed from
- <filename>pg_control</> and then exit without modifying anything.
- This is mainly a debugging tool, but can be useful as a sanity check
- before allowing <command>pg_resetxlog</command> to proceed for real.
+ <filename>pg_control</> and values to be used after reset and then exit
+ without modifying anything. This is mainly a debugging tool, but can be
+ useful as a sanity check before allowing <command>pg_resetxlog</command>
+ to proceed for real.
</para>
<para>
diff --git a/src/bin/pg_resetxlog/pg_resetxlog.c b/src/bin/pg_resetxlog/pg_resetxlog.c
index f1b5d6d..73faceb 100644
--- a/src/bin/pg_resetxlog/pg_resetxlog.c
+++ b/src/bin/pg_resetxlog/pg_resetxlog.c
@@ -64,10 +64,18 @@ static ControlFileData ControlFile; /* pg_control values */
static XLogSegNo newXlogSegNo; /* new XLOG segment # */
static bool guessed = false; /* T if we had to guess at any values */
static const char *progname;
+static uint32 set_xid_epoch = (uint32) -1;
+static TransactionId set_xid = 0;
+static Oid set_oid = 0;
+static MultiXactId set_mxid = 0;
+static MultiXactOffset set_mxoff = (MultiXactOffset) -1;
+static uint32 minXlogTli = 0;
+static XLogSegNo minXlogSegNo = 0;
static bool ReadControlFile(void);
static void GuessControlValues(void);
static void PrintControlValues(bool guessed);
+static void PrintNewControlValues(void);
static void RewriteControlFile(void);
static void FindEndOfXLOG(void);
static void KillExistingXLOG(void);
@@ -82,14 +90,7 @@ main(int argc, char *argv[])
int c;
bool force = false;
bool noupdate = false;
- uint32 set_xid_epoch = (uint32) -1;
- TransactionId set_xid = 0;
- Oid set_oid = 0;
- MultiXactId set_mxid = 0;
MultiXactId set_oldestmxid = 0;
- MultiXactOffset set_mxoff = (MultiXactOffset) -1;
- uint32 minXlogTli = 0;
- XLogSegNo minXlogSegNo = 0;
char *endptr;
char *endptr2;
char *DataDir;
@@ -302,6 +303,13 @@ main(int argc, char *argv[])
FindEndOfXLOG();
/*
+ * Print current control file parameters, if we had to guess anything and
+ * -f was not given or -n is given.
+ */
+ if ((guessed && !force) || noupdate)
+ PrintControlValues(guessed);
+
+ /*
* Adjust fields if required by switches. (Do this now so that printout,
* if any, includes these values.)
*/
@@ -352,11 +360,12 @@ main(int argc, char *argv[])
/*
* If we had to guess anything, and -f was not given, just print the
- * guessed values and exit. Also print if -n is given.
+ * values to be reset and exit. Also print value to be reset if -n is
+ * given.
*/
if ((guessed && !force) || noupdate)
{
- PrintControlValues(guessed);
+ PrintNewControlValues();
if (!noupdate)
{
printf(_("\nIf these values seem acceptable, use -f to force reset.\n"));
@@ -556,12 +565,11 @@ static void
PrintControlValues(bool guessed)
{
char sysident_str[32];
- char fname[MAXFNAMELEN];
if (guessed)
printf(_("Guessed pg_control values:\n\n"));
else
- printf(_("pg_control values:\n\n"));
+ printf(_("Current pg_control values:\n\n"));
/*
* Format system_identifier separately to keep platform-dependent format
@@ -570,10 +578,6 @@ PrintControlValues(bool guessed)
snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
ControlFile.system_identifier);
- XLogFileName(fname, ControlFile.checkPointCopy.ThisTimeLineID, newXlogSegNo);
-
- printf(_("First log segment after reset: %s\n"),
- fname);
printf(_("pg_control version number: %u\n"),
ControlFile.pg_control_version);
printf(_("Catalog version number: %u\n"),
@@ -632,6 +636,63 @@ PrintControlValues(bool guessed)
/*
+ * Print the values to be changed after pg_resetxlog.
+ *
+ * NB: this display should be just for those fields that are
+ * going to change after reset.
+ */
+static void
+PrintNewControlValues()
+{
+ char fname[MAXFNAMELEN];
+
+ /* This will be always printed in order to keep format same. */
+ printf(_("\n\nValues to be used after reset:\n\n"));
+
+ XLogFileName(fname, ControlFile.checkPointCopy.ThisTimeLineID, newXlogSegNo);
+ printf(_("First log segment after reset: %s\n"), fname);
+
+ if (set_mxid != 0)
+ {
+ printf(_("NextMultiXactId: %u\n"),
+ ControlFile.checkPointCopy.nextMulti);
+ printf(_("OldestMultiXid: %u\n"),
+ ControlFile.checkPointCopy.oldestMulti);
+ printf(_("OldestMulti's DB: %u\n"),
+ ControlFile.checkPointCopy.oldestMultiDB);
+ }
+
+ if (set_mxoff != -1)
+ {
+ printf(_("NextMultiOffset: %u\n"),
+ ControlFile.checkPointCopy.nextMultiOffset);
+ }
+
+ if (set_oid != 0)
+ {
+ printf(_("NextOID: %u\n"),
+ ControlFile.checkPointCopy.nextOid);
+ }
+
+ if (set_xid != 0)
+ {
+ printf(_("NextXID: %u\n"),
+ ControlFile.checkPointCopy.nextXid);
+ printf(_("OldestXID: %u\n"),
+ ControlFile.checkPointCopy.oldestXid);
+ printf(_("OldestXID's DB: %u\n"),
+ ControlFile.checkPointCopy.oldestXidDB);
+ }
+
+ if (set_xid_epoch != -1)
+ {
+ printf(_("NextXID Epoch: %u\n"),
+ ControlFile.checkPointCopy.nextXidEpoch);
+ }
+}
+
+
+/*
* Write out the new pg_control file.
*/
static void
@@ -1039,7 +1100,7 @@ usage(void)
printf(_(" -f force update to be done\n"));
printf(_(" -l XLOGFILE force minimum WAL starting location for new transaction log\n"));
printf(_(" -m MXID,MXID set next and oldest multitransaction ID\n"));
- printf(_(" -n no update, just show extracted control values (for testing)\n"));
+ printf(_(" -n no update, just show extracted and reset control values (for testing)\n"));
printf(_(" -o OID set next OID\n"));
printf(_(" -O OFFSET set next multitransaction offset\n"));
printf(_(" -V, --version output version information, then exit\n"));
On 29 November 2013, Amit Kapila Wrote:
Further Review of this patch:
b. why to display 'First log segment after reset' in 'Currrent
pg_control values' section as now the same information
is available in new section "Values to be used after reset:" ?May not be always. Suppose if user has given new value of seg no
andTLI, then it will be different.
Otherwise it will be same.
So now I have changed the code in such way that the value of XLOG
segment # read from checkpoint record gets printed as part of
current value and any further new value gets printed in Values to
be reset (This will be always at-least one plus the current value).
Because offollowing code in FindEndOfXLOG
xlogbytepos = newXlogSegNo *
ControlFile.xlog_seg_size;
newXlogSegNo = (xlogbytepos + XLogSegSize
-
1)
/ XLogSegSize;
newXlogSegNo++;
It can be different, but I don't think we should display it in both
sections because:
a. it doesn't belong to control file.
b. if you carefully look at original link
(/messages/by-id/1283277511-sup-2152@alvh.no-
ip.org),
these values are not getting displayed in pg_control valuessection.
So I suggest it is better to remove it from pg_control values
section.
Done as per suggestion.
I have done few more cosmetic changes in your patch, please find the
updated patch attached with this mail.
Kindly check once whether changes are okay.
Changes are fine. Thanks you.
Thanks and Regards,
Kumar Rajeev Rastogi
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Fri, Nov 29, 2013 at 10:00 AM, Rajeev rastogi
<rajeev.rastogi@huawei.com> wrote:
On 29 November 2013, Amit Kapila Wrote:
Further Review of this patch:
I have done few more cosmetic changes in your patch, please find the
updated patch attached with this mail.
Kindly check once whether changes are okay.Changes are fine. Thanks you.
I have uploaded the latest patch in CF app and marked it as Ready For Committer.
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 29 November 2013, Amit Kapila Wrote:
Further Review of this patch:
I have done few more cosmetic changes in your patch, please find the
updated patch attached with this mail.
Kindly check once whether changes are okay.Changes are fine. Thanks you.
I have uploaded the latest patch in CF app and marked it as Ready For
Committer.
Thanks a lot.
Thanks and Regards,
Kumar Rajeev Rastogi
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 11/29/2013 08:41 AM, Rajeev rastogi wrote:
On 29 November 2013, Amit Kapila Wrote:
Further Review of this patch:
I have done few more cosmetic changes in your patch, please find the
updated patch attached with this mail.
Kindly check once whether changes are okay.Changes are fine. Thanks you.
I have uploaded the latest patch in CF app and marked it as Ready For
Committer.Thanks a lot.
Committed, with some minor kibitzing of comments and docs. Thanks!
- Heikki
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 12 December 2013, Heikki Linnakangas Wrote:
Further Review of this patch:
I have done few more cosmetic changes in your patch, please find
the updated patch attached with this mail.
Kindly check once whether changes are okay.Changes are fine. Thanks you.
I have uploaded the latest patch in CF app and marked it as Ready
For
Committer.
Thanks a lot.
Committed, with some minor kibitzing of comments and docs. Thanks!
Thanks a lot..:-)
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers