spaghettidba / WorkloadTools

A collection of tools to collect, analyze and replay SQL Server workloads, on premises and in the cloud
MIT License
230 stars 51 forks source link

Attempt to make SqlWorkload.exe a service fails with 'Type cannot be instantiated' #149

Open schnorea opened 3 months ago

schnorea commented 3 months ago

I'm trying to run the commandline tool SqlWorkload.exe in mono in a docker container but I am getting an error when the Listener is getting instanced.

Process:

SqlWorkload.json

{
    "Controller": {

        "Listener":
        {
            "__type": "ExtendedEventsWorkloadListener",
            "ConnectionInfo":
            {
                "ServerName": "192.168.2.225",
                "DatabaseName": "MontyPython",
                "SchemaName": "dbo",
                "UserName": "sa",
                "Password": "PA55vv0rD"
            }
            //,
            //"DatabaseFilter": "benchmark",
            //"TraceRolloverCount": 100,
            //"TimeoutMinutes": 10
        },
        "Consumers":
        [
            {
                "__type": "WorkloadFileWriterConsumer",
                "OutputFile": "first_capture.sqlite"
            }
       ]
    }
}

Error message

root@6c93561df728:/WorkloadTools/SqlWorkload/bin/x64/Debug# mono --debug SqlWorkload.exe
Info - SqlWorkload.Program : SqlWorkload, Version=1.7.1.0, Culture=neutral, PublicKeyToken=null 1.7.1
Info - SqlWorkload.Program : Reading configuration from '/WorkloadTools/SqlWorkload/bin/x64/Debug/SqlWorkload.json'
Error - SqlWorkload.Program : System.FormatException: Unable to load configuration from '/WorkloadTools/SqlWorkload/bin/x64/Debug/SqlWorkload.json'. The file contains semantic errors. ---> System.ArgumentException: Type cannot be instantiated
Parameter name: type
  at (wrapper managed-to-native) System.Runtime.Remoting.Activation.ActivationServices.AllocateUninitializedClassInstance(System.Type)
  at System.Runtime.Serialization.FormatterServices.nativeGetUninitializedObject (System.RuntimeType type) [0x00000] in <de882a77e7c14f8ba5d298093dde82b2>:0 
  at System.Runtime.Serialization.FormatterServices.GetUninitializedObject (System.Type type) [0x00035] in <de882a77e7c14f8ba5d298093dde82b2>:0 
  at WorkloadTools.Util.ModelConverter.Deserialize (System.Collections.Generic.IDictionary`2[TKey,TValue] dictionary, System.Type type, System.Web.Script.Serialization.JavaScriptSerializer serializer) [0x0000e] in /WorkloadTools/WorkloadTools/Util/ModelConverter.cs:51 
  at WorkloadTools.Util.ModelConverter.Deserialize (System.Collections.Generic.IDictionary`2[TKey,TValue] dictionary, System.Type type, System.Web.Script.Serialization.JavaScriptSerializer serializer) [0x001c0] in /WorkloadTools/WorkloadTools/Util/ModelConverter.cs:89 
  at WorkloadTools.Util.ModelConverter.Deserialize (System.Collections.Generic.IDictionary`2[TKey,TValue] dictionary, System.Type type, System.Web.Script.Serialization.JavaScriptSerializer serializer) [0x001c0] in /WorkloadTools/WorkloadTools/Util/ModelConverter.cs:89 
  at System.Web.Script.Serialization.JavaScriptSerializer.ConvertToType (System.Object obj, System.Type targetType) [0x0003c] in <258c42715fee4479b0f6509f80f9cdc7>:0 
  at System.Web.Script.Serialization.JavaScriptSerializer.ConvertToType[T] (System.Object obj) [0x0000d] in <258c42715fee4479b0f6509f80f9cdc7>:0 
  at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T] (System.String input) [0x00008] in <258c42715fee4479b0f6509f80f9cdc7>:0 
  at WorkloadTools.Config.SqlWorkloadConfig.LoadFromFile (System.String path) [0x00066] in /WorkloadTools/WorkloadTools/Config/SqlWorkloadConfig.cs:50 
   --- End of inner exception stack trace ---
  at WorkloadTools.Config.SqlWorkloadConfig.LoadFromFile (System.String path) [0x00076] in /WorkloadTools/WorkloadTools/Config/SqlWorkloadConfig.cs:54 
  at SqlWorkload.Program.Run (SqlWorkload.Options options) [0x00198] in /WorkloadTools/SqlWorkload/Program.cs:102 
  at SqlWorkload.Program.Main (System.String[] args) [0x000c2] in /WorkloadTools/SqlWorkload/Program.cs:47 

In a previous attempt at debugging the issue I put in print statements to determine where things went sideways and what the type was that it was not able to instance.

The source seems to be at the p = System.Runtime.Serialization.FormatterServices.GetUninitializedObject(type); line in the ModelConverter.cs file as seen below.

The type it was attempting to get (and seems to fail at) was WorkloadTools.WorkloadListener. It did fine with the first pass were it got the WorkloadTools.WorkloadController.

        public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
        {
            object p;
            try
            {
                // try to create the object using its parameterless constructor
                p = Activator.CreateInstance(type);
            }
            catch {
                // try to create the object using this scary initializer that 
                // doesn't need the parameterless constructor
                p = System.Runtime.Serialization.FormatterServices.GetUninitializedObject(type);
            }

I verified the DB could be reached via the connection string I provided (the one above is modified) using sqlcmd from a docker container so I am pretty sure that works. Hunting around for what setup would cause GetUninitializedObject to fail didn't turn up anything.

Any ideas what might cause this would be appreciated.

spaghettidba commented 3 months ago

Hi, this looks like a very tricky issue. I never have tried to make WorkloadTools compile and run under Mono. Seems to me that System.Runtime.Serialization.FormatterServices.GetUninitializedObject(type); is implementation dependent. I don't think I can add much to your analysis, except that the exception is happening outside my code, probably in native code. Sorry, I wish I could help you but this is outside my area of expertise

schnorea commented 3 months ago

I appreciate the reply. I'm not as strong in C# either. I might take a look at creating a config file parser that is simpler when I get some time.

Another question: I have read alot about WorkloadTool and it seems like its can keep up with pretty high transacation rates. Any idea of the highest rate recorded to date might be?

Thank you

spaghettidba commented 2 months ago

Hi, sorry for the delay, I got a few health issues. I honestly don't know. I have been told it managed to capture the workload on servers with 20K batches per second. I have experienced myself over 3K batches replayed per second.