aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-07-08 22:17:55 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-07-08 22:17:55 +0000
commitc3c76c2de3b16b94ebe6f236400b753242937e68 (patch)
treeecc6af526873dd07d8ffb5d3ada83203295e0e2c /src
parent1b3dfb041a63d0f8d4ef8618b04b80fcedb8b4d7 (diff)
downloadpostgresql-c3c76c2de3b16b94ebe6f236400b753242937e68.tar.gz
postgresql-c3c76c2de3b16b94ebe6f236400b753242937e68.zip
Fix performance bug in write_syslog(): the code to preferentially break the
log message at newlines cost O(N^2) for very long messages with few or no newlines. For messages in the megabyte range this became the dominant cost. Per gripe from Achilleas Mantzios. Patch all the way back, since this is a safe change with no portability risks. I am also thinking of increasing PG_SYSLOG_LIMIT, but that should be done separately.
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/error/elog.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 06447251346..3855c60d3fd 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -42,7 +42,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.178.2.4 2007/07/21 22:12:11 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.178.2.5 2008/07/08 22:17:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1205,6 +1205,7 @@ write_syslog(int level, const char *line)
static unsigned long seq = 0;
int len;
+ const char *nlpos;
/* Open syslog connection if not done yet */
if (!openlog_done)
@@ -1227,17 +1228,17 @@ write_syslog(int level, const char *line)
* fact, it does work around by splitting up messages into smaller pieces.
*
* We divide into multiple syslog() calls if message is too long or if the
- * message contains embedded NewLine(s) '\n'.
+ * message contains embedded newline(s).
*/
len = strlen(line);
- if (len > PG_SYSLOG_LIMIT || strchr(line, '\n') != NULL)
+ nlpos = strchr(line, '\n');
+ if (len > PG_SYSLOG_LIMIT || nlpos != NULL)
{
int chunk_nr = 0;
while (len > 0)
{
char buf[PG_SYSLOG_LIMIT + 1];
- const char *nlpos;
int buflen;
int i;
@@ -1246,11 +1247,12 @@ write_syslog(int level, const char *line)
{
line++;
len--;
+ /* we need to recompute the next newline's position, too */
+ nlpos = strchr(line, '\n');
continue;
}
/* copy one line, or as much as will fit, to buf */
- nlpos = strchr(line, '\n');
if (nlpos != NULL)
buflen = nlpos - line;
else