Category Archives: Development

MSSQL: Neměňte „Maximum server memory (in MB)“ na 0

Dneska jsem se nechal unést a chtěl jsem vypnout na MS SQL 2008 R2 horní mez využité paměti, kterou jsme měli na serveru staženou na 2.5 GB.

Nu což, vlezl jsem do SQL Management Studia, dal jsem si vlastnosti serveru, koukám do nastavení Memory a změnil jsem nastavení vlastnosti „Maximum server memory (in MB)“ z 2500 na 0 (velmi naivně jsem předpokládal, že stejně jako jinde to bude interpretováno jako „no limit“).

Omyl, to nezkoušejte. Poslední, co jsem ještě záhledl bylo, že si to SQL sám změnil na 16 (MB) a to bylo na dlouho všechno, co jsem z SQL serveru viděl.

Následný pokus změny na vyšší hodnotu už SQL Management Studio neprovedlo, nové připojení na SQL Management Studio už neúspěšné (ani nevytvořil connection).

Zůstal viset ve stavu, kdy si nechal asi 500 MB paměti a bral 25% CPU, což nekleslo ani po odpojení zátěže (kterou již stejně neodbavoval).

Stop service nic, takže kill procesu z task manageru.

Nový start service, zabraná paměť procesem 70 MB, bez šance na připojení z Management Studia.

Zkouším OSQL, sp_reconfigure, nic, hlášky typu „There is insufficient system memory in resource pool ‚internal‘ to run this query.“, nebo se vůbec nevytvoří connection.

Nakonec jsem to vybojoval na několikátý pokus (vždy těsně po startu service) přes „sqlcmd -A -E“ (Dedicated Administrator Connection) a volby

sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'max server memory', 2147483647;
GO
RECONFIGURE;
GO

…horká půlhodinka.

VaDo said:

Nepomohlo nastartovat SQL server z command line? http://msdn.microsoft.com/en-us/library/ms190737.aspx

David Hlaváček said:

Právě pro tyto stavy je k dispozici DAC (Dedicated Administrator Connection). Je to vyhrazené připojení pro systémového administrátora, které má přednostní právo v přidělení prostředků. V praxi se SQL Server z důvodu nedostatku paměti může dostat do stavu, který je ve článku posán.

Management Studio dokáže DAC použít také, tam je to o změně connection stringu kdy v před název serveru se uvede ADMIN: tedy „ADMIN:SQLServer1“.

DAC je standardně zapnuto pouze lokálně tzn. protokol Shared memory. Pokud by se tedy celý server dostal do problémů s pamětí, DAC není nic platné, když ho lokálně nevytvoříme. Proto je možné zapnout DAC s možností vzdáleného přístupu, což je vlastnost, která je po instalaci standardně zablokována a je nutné ji povolit.

Návrh schématu databáze – Slides a ukázkové DB [TechEd Praha 2011]

Slides a vzorové DB z přednášky pro TechEd Praha 2011:

Záznam z přednášky nebyl pořizován, jiná verze téže přednášky však byla prezentována pro MS Fest Praha 2011 a k té záznam existuje.

Český stemmer do MSSQL 2008 R2 x64

Dneska se budu s laskavým svolením chlubit cizím peřím, uvádím postup (mnou neověřený, ale z důvěryhodného zdroje – od Roberta Kindla z firmy EXEC), jak do MS SQL 2008 R2 x64 dostat český stemmer pro fultextové vyhledávání:

****

musis nainstalovat Microsoft Search Server 2010 Express – to by melo byt zdarma a cesky stemmer to obsahuje

bohuzel je ale ten stemmer dostupny jen v tom Sharepointu (neregistruje se to do systemu)

takze jsem vlasnimi silami vyhackoval toto:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10_50.SQL2008R2\MSSearch\Language\ces]
„TsaurusFile“=“tsces.xml“
„Locale“=dword:00000405
„WBreakerClass“=“{468bfc77-3876-4a47-a6ff-f5f6e8ea7968}“
„StemmerClass“=“{f51b7203-9bf9-4c39-b655-18fad8fa8a9a}“
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10_50.SQL2008R2\MSSearch\CLSID\{f51b7203-9bf9-4c39-b655-18fad8fa8a9a}]
@=“c:\\Program Files\\Microsoft Office Servers\\14.0\\Bin\\mswb7.dll“
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL10_50.SQL2008R2\MSSearch\CLSID\{468bfc77-3876-4a47-a6ff-f5f6e8ea7968}]
@=“c:\\Program Files\\Microsoft Office Servers\\14.0\\Bin\\mswb7.dll“
toto konkretne zaregistruje ten cesky stemmer z Microsoft Search Server 2010 Express do MSSQL 2008 R2 (pro MSSQL 2008 a MSSQL 2005 by to zrejme slo podobne)

pak uz staci jen
exec sp_fulltext_service ‚update_languages‘;
exec sp_fulltext_service ‚restart_all_fdhosts‘;

overeni instalace (vypise se stemmer) s lcid 1029
exec sp_help_fulltext_system_components wordbreaker
SELECT * FROM sys.fulltext_languages order by lcid

sklonovat to umi:
select * from sys.dm_fts_parser(‚FORMSOF(INFLECTIONAL, květina)‘, 1029, 0, 0)

++++

jeste je asi treba tohle:
copy „c:\Program Files\Microsoft Office Servers\14.0\Data\Config\tsces.xml“ „c:\MSSQL2008R2\FTData“ (do slozky k ostatnim ts???.xml)
Noise Words, ktere jsou v Sharepointu 2010 ulozeny v c:\Program Files\Microsoft Office Servers\14.0\Data\Config\noiseces.txt by se na MSSQL 2008 R2 mely konfigurovat pres CREATE FULLTEXT STOPLIST

SmtpTraceListener – mailování výstupů trace

V návaznosti na používání ExceptionTraceru, který pomocí standardní .NET mechanizmů Trace/TraceSource loguje neobsloužené výjimky, jsem dopsal jednoduchý TraceListener, který lze používání pro mailování těchto výjimek na určený mail. Cílovým scénářem je tedy automatické mailování výjimek z consolových/WinForm aplikací, či spíše utilit. Není to zatím příliš vyladěno, spíše takový náznak, jakou cestou se vydat.

Do činnosti se to zapojuje zhruba takto (app.config):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.diagnostics>
        <sources>
            <source name="Exceptions" switchValue="Error">
                	<listeners>
<!--                    <add name="XmlListener" initializeData="Exceptions.xml" type="System.Diagnostics.XmlWriterTraceListener"/>
                    <add name="TextWriterListener" initializeData="Exceptions.log" type="System.Diagnostics.TextWriterTraceListener"/>
-->
                    <add name="SmtpListener" initializeData="Subject=Chyby z mojí utility;To=errors@firma.cz" type="Havit.Diagnostics.SmtpTraceListener, Havit"/>
                </listeners>
            </source>
        </sources>
    </system.diagnostics>
    <system.net>
        <mailSettings>
            <smtp deliveryMethod="Network" from="neco@nekde.cz">
                <network host="mail.server.cz"/>
            </smtp>
        </mailSettings>
    </system.net>
</configuration>

Základem je implementovat třídu dědící z předka TraceListener:

  /// <summary>
    /// TraceListener, který výstup posílá mailem.
    /// </summary>
    /// <remarks>
    /// Inspirováno implementaci System.Diagnostics.XmlWriterListener.
    /// </remarks>
    public class SmtpTraceListener : TraceListener
    {
        #region MailTo
        /// <summary>
        /// E-mailová adresa, na kterou se posílají zprávy.
        /// </summary>
        public string MailTo
        {
            get
            {
                if (_mailTo == null)
                {
                    return "devmail@havit.cz";
                }
                return _mailTo;
            }
            set
            {
                _mailTo = value;
            }
        }
        private string _mailTo;
        #endregion

        #region Subject
        /// <summary>
        /// Subject zprávy.
        /// </summary>
        public string Subject
        {
            get
            {
                if (_subject == null)
                {
                    return "SmtpTraceListener";
                }
                return _subject;
            }
            set
            {
                _subject = value;
            }
        }
        private string _subject;
        #endregion

        #region Constructors
        /// <summary>
        /// Constructor, který je volán při použití TraceListerneru z app.configu a předává se do něj hodnota atributu initializeData.
        /// </summary>
        /// <param name="initializeData">hodnota atributu initializeData z app.config</param>
        public SmtpTraceListener(string initializeData)
        {
            if (initializeData == null)
            {
                return; // použijí se defaulty                
            }

            foreach (string arg in initializeData.Split(';'))
            {
                string[] paramValue = arg.Split('=');
                if (paramValue.Length >= 2)
                {
                    switch (paramValue[0].Trim().ToUpper())
                    {
                        case "TO":
                            MailTo = paramValue[1].Trim();
                            break;
                        case "SUBJECT":
                            Subject = paramValue[1].Trim();
                            break;
                        default:
                            throw new InvalidOperationException("Neznámý parametr konfigurace SmtpTraceListeneru v initializeData.");
                    }
                }
            }
        }
        #endregion

        #region SendMessage
        /// <summary>
        /// Interní implementace odesílání mailu.
        /// </summary>
        /// <param name="message">zpráva z trace</param>
        private void SendMessage(string message)
        {
            if (String.IsNullOrEmpty(this.MailTo))
            {
                return;
            }

            try
            {
                MailMessage mailMessage = new MailMessage();
                mailMessage.To.Add(this.MailTo);
                mailMessage.Subject = this.Subject;
                mailMessage.Body = message;
                SmtpClient smtpClient = new SmtpClient();
                smtpClient.Send(mailMessage);
            }
            catch
            {
                // NOOP - nechceme, aby nám nefunkční trace-mailing zabil server
#if DEBUG
                // při debugování nás to ale zajímá
                throw;
#endif
            }

            // http://www.codeproject.com/KB/trace/smtptracelistenerarticle.aspx
            // In the SMTPTraceListener Write method - I call the Flush method. This forces the e-mail output to happen right then, and makes the component more stable.
            // With the Flush taken out of the Write method, I was experiencing some inconsistent behavior - i.e. exceptions thrown sometimes but not always...
            // goofy problem perhaps someone knows why?
            this.Flush();
        }
        #endregion

        #region SendTrace
        /// <summary>
        /// Hlavní interní implementace sestavení mailu.
        /// </summary>
        /// <param name="eventCache">A <see cref="T:System.Diagnostics.TraceEventCache"/> object that contains the current process ID, thread ID, and stack trace information.</param>
        /// <param name="source">A name used to identify the output, typically the name of the application that generated the trace event.</param>
        /// <param name="eventType">One of the <see cref="T:System.Diagnostics.TraceEventType"/> values specifying the type of event that has caused the trace.</param>
        /// <param name="id">A numeric identifier for the event.</param>
        /// <param name="data">An array of objects to emit as data. Pokud je string, obsahuje přímo text zprávy.</param>
        private void SendTrace(TraceEventCache eventCache, string source, TraceEventType eventType, int id, params object[] data)
        {
            StringBuilder message = new StringBuilder();
            foreach (object item in data)
            {
                if (item != null)
                {
                    message.AppendLine(item.ToString());
                }
            }
            message.AppendLine();

            message.Append("CommandLine: ");
            message.AppendLine(Environment.CommandLine);

            message.Append("CurrentDirectory: ");
            message.AppendLine(Environment.CurrentDirectory);

            message.Append("MachineName: ");
            message.AppendLine(Environment.MachineName);

            message.Append("UserDomainName: ");
            message.AppendLine(Environment.UserDomainName);

            message.Append(".NET Framework: ");
            message.AppendLine(Environment.Version.ToString());

            if (eventCache != null)
            {
                message.AppendLine();
                message.AppendLine("Call stack:");
                message.AppendLine(eventCache.Callstack);
                message.AppendLine();

                message.AppendLine("Logical operation stack:");
                foreach (object item in eventCache.LogicalOperationStack)
                {
                    if (item != null)
                    {
                        message.AppendLine(item.ToString());
                    }
                }
                message.AppendLine();

                message.Append("DateTime: ");
                message.AppendLine(eventCache.DateTime.ToString());

                message.Append("Timestamp: ");
                message.AppendLine(eventCache.Timestamp.ToString());

                message.Append("ProcessId: ");
                message.AppendLine(eventCache.ProcessId.ToString());

                message.Append("ThreadId: ");
                message.AppendLine(eventCache.ThreadId);
            }

            if (!String.IsNullOrEmpty(source))
            {
                message.Append("Source: ");
                message.AppendLine(source);
            }

            message.Append("EventType: ");
            message.AppendLine(eventType.ToString("g"));

            message.Append("EventId: ");
            message.AppendLine(id.ToString("g"));

            SendMessage(message.ToString());
        }
        #endregion

        #region TraceData (override)
        /// <summary>
        /// Writes trace information, an array of data objects and event information to the listener specific output.
        /// </summary>
        /// <param name="eventCache">A <see cref="T:System.Diagnostics.TraceEventCache"/> object that contains the current process ID, thread ID, and stack trace information.</param>
        /// <param name="source">A name used to identify the output, typically the name of the application that generated the trace event.</param>
        /// <param name="eventType">One of the <see cref="T:System.Diagnostics.TraceEventType"/> values specifying the type of event that has caused the trace.</param>
        /// <param name="id">A numeric identifier for the event.</param>
        /// <param name="data">An array of objects to emit as data.</param>
        /// <PermissionSet>
        ///     <IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/>
        ///     <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode"/>
        /// </PermissionSet>
        public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, params object[] data)
        {
            if ((Filter == null) || Filter.ShouldTrace(eventCache, source, eventType, id, null, null, null, data))
            {
                SendTrace(eventCache, source, eventType, id, data);
            }
        }

        /// <summary>
        /// Writes trace information, an array of data objects and event information to the listener specific output.
        /// </summary>
        /// <param name="eventCache">A <see cref="T:System.Diagnostics.TraceEventCache"/> object that contains the current process ID, thread ID, and stack trace information.</param>
        /// <param name="source">A name used to identify the output, typically the name of the application that generated the trace event.</param>
        /// <param name="eventType">One of the <see cref="T:System.Diagnostics.TraceEventType"/> values specifying the type of event that has caused the trace.</param>
        /// <param name="id">A numeric identifier for the event.</param>
        /// <param name="data">An array of objects to emit as data.</param>
        /// <PermissionSet>
        ///     <IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/>
        ///     <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode"/>
        /// </PermissionSet>
        public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data)
        {
            if ((Filter == null) || Filter.ShouldTrace(eventCache, source, eventType, id, null, null, data, null))
            {
                SendTrace(eventCache, source, eventType, id, data);
            }
        }
        #endregion

        #region TraceEvent (override)
        /// <summary>
        /// Writes trace information, a message, and event information to the listener specific output.
        /// </summary>
        /// <param name="eventCache">A <see cref="T:System.Diagnostics.TraceEventCache"/> object that contains the current process ID, thread ID, and stack trace information.</param>
        /// <param name="source">A name used to identify the output, typically the name of the application that generated the trace event.</param>
        /// <param name="eventType">One of the <see cref="T:System.Diagnostics.TraceEventType"/> values specifying the type of event that has caused the trace.</param>
        /// <param name="id">A numeric identifier for the event.</param>
        /// <param name="message">A message to write.</param>
        /// <PermissionSet>
        ///     <IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/>
        ///     <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode"/>
        /// </PermissionSet>
        public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message)
        {
            if ((Filter == null) || Filter.ShouldTrace(eventCache, source, eventType, id, message, null, null, null))
            {
                SendTrace(eventCache, source, eventType, id, message);
            }
        }

        /// <summary>
        /// Writes trace information, a formatted array of objects and event information to the listener specific output.
        /// </summary>
        /// <param name="eventCache">A <see cref="T:System.Diagnostics.TraceEventCache"/> object that contains the current process ID, thread ID, and stack trace information.</param>
        /// <param name="source">A name used to identify the output, typically the name of the application that generated the trace event.</param>
        /// <param name="eventType">One of the <see cref="T:System.Diagnostics.TraceEventType"/> values specifying the type of event that has caused the trace.</param>
        /// <param name="id">A numeric identifier for the event.</param>
        /// <param name="format">A format string that contains zero or more format items, which correspond to objects in the <paramref name="args"/> array.</param>
        /// <param name="args">An object array containing zero or more objects to format.</param>
        /// <PermissionSet>
        ///     <IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/>
        ///     <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode"/>
        /// </PermissionSet>
        public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args)
        {
            if ((Filter == null) || Filter.ShouldTrace(eventCache, source, eventType, id, format, args, null, null))
            {
                SendTrace(eventCache, source, eventType, id, String.Format(CultureInfo.InvariantCulture, format, args));
            }
        }
        #endregion

        #region TraceTransfer (override)
        /// <summary>
        /// Writes trace information, a message, a related activity identity and event information to the listener specific output.
        /// </summary>
        /// <param name="eventCache">A <see cref="T:System.Diagnostics.TraceEventCache"/> object that contains the current process ID, thread ID, and stack trace information.</param>
        /// <param name="source">A name used to identify the output, typically the name of the application that generated the trace event.</param>
        /// <param name="id">A numeric identifier for the event.</param>
        /// <param name="message">A message to write.</param>
        /// <param name="relatedActivityId">A <see cref="T:System.Guid"/> object identifying a related activity.</param>
        public override void TraceTransfer(TraceEventCache eventCache, string source, int id, string message, Guid relatedActivityId)
        {
            SendTrace(eventCache, source, TraceEventType.Transfer, id, String.Format("{0} : {1}", message, relatedActivityId));
        }
        #endregion

        #region Write, WriteLine (override)
        /// <summary>
        /// When overridden in a derived class, writes the specified message to the listener you create in the derived class.
        /// </summary>
        /// <param name="message">A message to write.</param>
        public override void Write(string message)
        {
            TraceEvent(null, "Write", TraceEventType.Information, 0, message);
        }

        /// <summary>
        /// When overridden in a derived class, writes a message to the listener you create in the derived class, followed by a line terminator.
        /// </summary>
        /// <param name="message">A message to write.</param>
        public override void WriteLine(string message)
        {
            this.Write(message);
        }
        #endregion
    }

Tipy a triky T-SQL z praxe – Slides a dema [TechEd Praha 2010]

Slides a dema z přednášky na konferenci TechEd Praha 2010:

Záznam z přednášky nebyl pořizován.

Povinné a volitelné parametry v C# 4.0 – Dema [MS Days 2010]

Dema z mého příspěvku na konferenci MS Days 2010 – Demománii:

Ze vstupu nebyl pořizován záznam.

Optimalizace výkonu webových aplikací – Slides, dema a záznam [MS Fest 2010]

Slides a dema z přednášky na konferenci MS Fest 2010 (tentokrát se zaměřením na client-side a přenos):

Z přednášky byl pořizován obrazový záznam (HD 720p), který najdete na našem YouTube Channelu:

Code Contracts – Slides a dema [TechEd Praha 2010]

Slides a dema z přednášky na konferenci TechEd Praha 2010:

Záznam z přednášky nebyl pořizován.

Ladění výkonu webových aplikací – Slides a dema [TechEd Praha 2010]

Slides a dema z přednášky na konferenci TechEd Praha 2010:

Záznam z přednášky nebyl pořizován, rozšířená podoba byla však prezentována pro WUG Praha a k té záznam existuje.

WebResource.axd: This is an invalid webresource request. Špatné datum na serveru.

Symptom

Všechny requesty na WebResource.axd (včetně základních na .NET skripty) končí chybou 404 – „This is an invalid webresource request.“, resp. „Toto je neplatný požadavek webového prostředku.“

Cause

Problém byl v tom, že na serveru byl nastaven čas o několik měsíců nazpět.

Jestli tomu vadí, že aplikace byla kompilována později, než je datum/čas na serveru, nebo co konkrétně je problém, to jsem nehledal. Každopádně navrácení korektního data okamžitě problém vyřešilo.