Changeset: 7a02eb06c46e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=7a02eb06c46e
Modified Files:
        clients/mapiclient/stethoscope.c
        monetdb5/mal/mal_profiler.c
        monetdb5/mal/mal_profiler.h
        monetdb5/mal/mal_runtime.c
        monetdb5/modules/mal/profiler.c
        monetdb5/modules/mal/profiler.h
        monetdb5/modules/mal/profiler.mal
        sql/backends/monet5/sql_execute.c
Branch: default
Log Message:

If the system crashes during a SQL TRACE command then the trace
info was available in the dbfarm as a scratch file.
It interfered with the stethoscope tracing.
In general, it is better to use the stethoscope for tracing
and the dbfarm is generally not accessible.
This non-documented feature is removed.


diffs (truncated from 404 to 300 lines):

diff --git a/clients/mapiclient/stethoscope.c b/clients/mapiclient/stethoscope.c
--- a/clients/mapiclient/stethoscope.c
+++ b/clients/mapiclient/stethoscope.c
@@ -232,7 +232,6 @@ usageStethoscope(void)
     fprintf(stderr, "  -h | --host=<hostname>\n");
     fprintf(stderr, "  -c | --convert=<old formated file>\n");
     fprintf(stderr, "  -j | --json\n");
-    fprintf(stderr, "  -y | --pretty (implies --json)\n");
     fprintf(stderr, "  -o | --output=<file>\n");
     fprintf(stderr, "  -b | --beat=<delay> in milliseconds (default 50)\n");
     fprintf(stderr, "  -D | --debug\n");
@@ -347,11 +346,7 @@ main(int argc, char **argv)
                        break;
                case 'j':
                        json = 1;
-                       stream_mode = 3;
-                       break;
-               case 'y':
                        stream_mode = 1;
-                       json = 1;
                        break;
                case 'o':
                        filename = strdup(optarg);
diff --git a/monetdb5/mal/mal_profiler.c b/monetdb5/mal/mal_profiler.c
--- a/monetdb5/mal/mal_profiler.c
+++ b/monetdb5/mal/mal_profiler.c
@@ -17,6 +17,7 @@
 #include "monetdb_config.h"
 #include "mutils.h"         /* mercurial_revision */
 #include "msabaoth.h"          /* msab_getUUID */
+#include "mal_authorize.h"
 #include "mal_function.h"
 #include "mal_listing.h"
 #include "mal_profiler.h"
@@ -31,7 +32,6 @@
 #include <string.h>
 
 static str myname = 0; // avoid tracing the profiler module
-static int eventcounter = 0;
 
 /* The JSON rendering can be either using '\n' separators between
  * each key:value pair or as a single line using ' '*/
@@ -44,6 +44,7 @@ static int eventcounter = 0;
 
 
 int malProfileMode = 0;     /* global flag to indicate profiling mode */
+static Client malprofileruser;
 
 static struct timeval startup_time;
 
@@ -54,10 +55,6 @@ struct rusage infoUsage;
 static struct rusage prevUsage;
 #endif
 
-
-
-/* the heartbeat process produces a ping event once every X milliseconds */
-
 #define LOGLEN 8192
 #define lognew()  loglen = 0; logbase = logbuffer; *logbase = 0;
 
@@ -79,7 +76,6 @@ static struct rusage prevUsage;
 static void logjsonInternal(char *logbuffer)
 {
        size_t len;
-
        len = strlen(logbuffer);
 
        MT_lock_set(&mal_profileLock);
@@ -140,8 +136,8 @@ renderProfilerEvent(Client cntxt, MalBlk
        size_t loglen;
        str stmt, c;
        str stmtq;
-       lng usec= GDKusec();
-       uint64_t microseconds = (uint64_t)startup_time.tv_sec*1000000 + 
(uint64_t)startup_time.tv_usec + (uint64_t)usec;
+       lng usec;
+       uint64_t microseconds;
 
        /* ignore generation of events for instructions that are called too 
often
         * they may appear when BARRIER blocks are executed
@@ -153,6 +149,14 @@ renderProfilerEvent(Client cntxt, MalBlk
                return;
        }
 
+/* The stream of events can be complete read by the DBA, 
+ * all other users can only see events assigned to their account
+ */
+       if( malprofileruser->user != MAL_ADMIN && malprofileruser->user != 
cntxt->user)
+               return;
+
+       usec= GDKusec();
+       microseconds = (uint64_t)startup_time.tv_sec*1000000 + 
(uint64_t)startup_time.tv_usec + (uint64_t)usec;
        /* make profile event tuple  */
        lognew();
        logadd("{"PRETTIFY); // fill in later with the event counter
@@ -473,7 +477,7 @@ profilerHeartbeatEvent(char *alter)
        lng usec = GDKusec();
        uint64_t microseconds = (uint64_t)startup_time.tv_sec*1000000 + 
(uint64_t)startup_time.tv_usec + (uint64_t)usec;
 
-       if (ATOMIC_GET(&hbdelay) == 0 || maleventstream  == NULL)
+       if (ATOMIC_GET(&hbdelay) == 0 || malprofileruser  == NULL)
                return;
 
        /* get CPU load on beat boundaries only */
@@ -531,16 +535,12 @@ profilerEvent(Client cntxt, MalBlkPtr mb
        }
 }
 
-/* The first scheme dumps the events
- * on a stream (and in the pool)
- * The mode encodes two flags:
- * - showing all running instructions
- * - single line json
+/* The first scheme dumps the events on a stream (and in the pool)
  */
 #define PROFSHOWRUNNING        1
 #define PROFSINGLELINE 2
 str
-openProfilerStream(Client cntxt, stream *fd, int mode)
+openProfilerStream(Client cntxt, int mode)
 {
        int j;
 
@@ -550,13 +550,18 @@ openProfilerStream(Client cntxt, stream 
 #endif
        if (myname == 0){
                myname = putName("profiler");
-               eventcounter = 0;
                logjsonInternal(monet_characteristics);
        }
-       if( maleventstream)
-               closeProfilerStream(cntxt);
+       if( maleventstream){
+               /* The DBA can always grab the stream, others have to wait */
+               if ( cntxt->user == MAL_ADMIN)
+                       closeProfilerStream(cntxt);
+               else
+                       throw(MAL,"profiler.start","Profiler already running, 
stream not available");
+       }
        malProfileMode = -1;
-       maleventstream = fd;
+       maleventstream = cntxt->fdout;
+       malprofileruser = cntxt;
        (void) mode;
        // Ignore the JSON rendering mode, use compiled time version
        // prettify = (mode & PROFSINGLELINE) ? "": "\n";
@@ -580,6 +585,7 @@ closeProfilerStream(Client cntxt)
        (void) cntxt;
        maleventstream = NULL;
        malProfileMode = 0;
+       malprofileruser = 0;
        return MAL_SUCCEED;
 }
 
@@ -601,7 +607,6 @@ startProfiler(Client cntxt)
        MT_lock_set(&mal_profileLock );
        if (myname == 0){
                myname = putName("profiler");
-               eventcounter = 0;
        }
        malProfileMode = 1;
        MT_lock_unset(&mal_profileLock);
@@ -612,64 +617,19 @@ startProfiler(Client cntxt)
        return MAL_SUCCEED;
 }
 
-/* The trace information can be concurrently written to a file.
- * A hard limit is currently imposed */
-#define MAXTRACEFILES 50
-static int offlinestore = 0;
-static int tracecounter = 0;
+/* SQL tracing is simplified, because it only collects the events in the 
temporary table.
+ */
 str
-startTrace(Client cntxt, str path)
+startTrace(Client cntxt)
 {
-       int len;
-       char buf[FILENAME_MAX];
-
-       (void) cntxt;
-       if (path && maleventstream == NULL){
-               // create a file to keep the events, unless we
-               // already have a profiler stream
-               MT_lock_set(&mal_profileLock );
-               if(maleventstream == NULL && offlinestore ==0){
-                       len = 
snprintf(buf,FILENAME_MAX,"%s%c%s",GDKgetenv("gdk_dbpath"), DIR_SEP, path);
-                       if (len == -1 || len >= FILENAME_MAX) {
-                               MT_lock_unset(&mal_profileLock);
-                               throw(MAL, "profiler.startTrace", 
SQLSTATE(HY001) "Profiler filename path is too large");
-                       }
-                       if (mkdir(buf, MONETDB_DIRMODE) < 0 && errno != EEXIST) 
{
-                               MT_lock_unset(&mal_profileLock);
-                               throw(MAL, "profiler.startTrace", 
SQLSTATE(42000) "Failed to create directory %s", buf);
-                       }
-                       len = 
snprintf(buf,FILENAME_MAX,"%s%c%s%ctrace_%d",GDKgetenv("gdk_dbpath"), DIR_SEP, 
path,DIR_SEP,tracecounter++ % MAXTRACEFILES);
-                       if (len == -1 || len >= FILENAME_MAX) {
-                               MT_lock_unset(&mal_profileLock);
-                               throw(MAL, "profiler.startTrace", 
SQLSTATE(HY001) "Profiler filename path is too large");
-                       }
-                       if ((maleventstream = open_wastream(buf)) == NULL) {
-                               MT_lock_unset(&mal_profileLock );
-                               throw(MAL,"profiler.startTrace", 
SQLSTATE(HY001) MAL_MALLOC_FAIL);
-                       }
-                       offlinestore++;
-               }
-               MT_lock_unset(&mal_profileLock );
-       }
-       malProfileMode = 1;
        cntxt->sqlprofiler = TRUE;
        clearTrace(cntxt);
        return MAL_SUCCEED;
 }
 
 str
-stopTrace(Client cntxt, str path)
+stopTrace(Client cntxt)
 {
-       (void) cntxt;
-       MT_lock_set(&mal_profileLock );
-       if( path &&  offlinestore){
-               (void) close_stream(maleventstream);
-               maleventstream = 0;
-               offlinestore =0;
-       }
-       MT_lock_unset(&mal_profileLock );
-
-       malProfileMode = maleventstream != NULL;
        cntxt->sqlprofiler = FALSE;
        return MAL_SUCCEED;
 }
@@ -907,6 +867,7 @@ void profilerGetCPUStat(lng *user, lng *
        *iowait = corestat[255].iowait;
 }
 
+/* the heartbeat process produces a ping event once every X milliseconds */
 static MT_Id hbthread;
 static ATOMIC_TYPE hbrunning = ATOMIC_VAR_INIT(0);
 
diff --git a/monetdb5/mal/mal_profiler.h b/monetdb5/mal/mal_profiler.h
--- a/monetdb5/mal/mal_profiler.h
+++ b/monetdb5/mal/mal_profiler.h
@@ -23,7 +23,7 @@ typedef struct rusage Rusage;
 mal_export int malProfileMode;
 
 mal_export void initProfiler(void);
-mal_export str openProfilerStream(Client cntxt, stream *fd, int mode);
+mal_export str openProfilerStream(Client cntxt, int mode);
 mal_export str closeProfilerStream(Client cntxt);
 
 mal_export void profilerEvent(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci, int start);
@@ -31,8 +31,8 @@ mal_export void sqlProfilerEvent(Client 
 
 mal_export str startProfiler(Client cntxt);
 mal_export str stopProfiler(Client cntxt);
-mal_export str startTrace(Client cntxt, str path);
-mal_export str stopTrace(Client cntxt, str path);
+mal_export str startTrace(Client cntxt);
+mal_export str stopTrace(Client cntxt);
 mal_export void setHeartbeat(int delay);
 mal_export void initHeartbeat(void);
 mal_export void profilerHeartbeatEvent(char *alter);
diff --git a/monetdb5/mal/mal_runtime.c b/monetdb5/mal/mal_runtime.c
--- a/monetdb5/mal/mal_runtime.c
+++ b/monetdb5/mal/mal_runtime.c
@@ -9,9 +9,7 @@
 /* Author(s) M.L. Kersten
  * The MAL Runtime Profiler and system queue
  * This little helper module is used to perform instruction based profiling.
- * We should actually keep a little list of recently executed queries to 
inspection.
- * [TODO] It should be moved into the Client record for speed (>500 client 
connections)
- * Long term archival is left to the SQL history management structure
+ * The QRYqueue is only update at the start/finish of a query. 
  */
 
 #include "monetdb_config.h"
@@ -26,7 +24,6 @@
 #include "mal_private.h"
 
 
-// Keep a queue of running queries
 QueryQueue QRYqueue;
 lng qtop;
 static lng qsize;
@@ -221,11 +218,10 @@ runtimeProfileExit(Client cntxt, MalBlkP
        pci->totticks += pci->ticks;
        pci->calls++;
        
-       if(malProfileMode > 0 ){
+       if(malProfileMode > 0 )
                profilerEvent(cntxt, mb, stk, pci, FALSE);
-               if( cntxt->sqlprofiler )
-                       sqlProfilerEvent(cntxt, mb, stk, pci);
-       }
+       if( cntxt->sqlprofiler )
+               sqlProfilerEvent(cntxt, mb, stk, pci);
        if( malProfileMode < 0){
                /* delay profiling until you encounter start of MAL function */
                if( getInstrPtr(mb,0) == pci)
diff --git a/monetdb5/modules/mal/profiler.c b/monetdb5/modules/mal/profiler.c
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to