| 
 |  | 
Table of Contents
This appendix helps you port MySQL to other operating systems. Do check the list of currently supported operating systems first. See Section 2.1.1, “Operating Systems Supported by MySQL”. If you have created a new port of MySQL, please let us know so that we can list it here and on our Web site (http://www.mysql.com/), recommending it to other users.
Note: If you create a new port of MySQL, you are free to copy and distribute it under the GPL license, but it does not make you a copyright holder of MySQL.
    A working POSIX thread library is needed for the server. On Solaris
    2.5 we use Sun PThreads (the native thread support in 2.4 and
    earlier versions is not good enough), on Linux we use LinuxThreads
    by Xavier Leroy, <Xavier.Leroy@inria.fr>.
  
    The hard part of porting to a new Unix variant without good native
    thread support is probably to port MIT-pthreads. See
    mit-pthreads/README and Programming POSIX
    Threads (http://www.humanfactor.com/pthreads/).
  
Up to MySQL 4.0.2, the MySQL distribution included a patched version of Chris Provenzano's Pthreads from MIT (see the MIT Pthreads Web page at http://www.mit.edu/afs/sipb/project/pthreads/ and a programming introduction at http://www.mit.edu:8001/people/proven/IAP_2000/). These can be used for some operating systems that do not have POSIX threads. See Section 2.8.5, “MIT-pthreads Notes”.
It is also possible to use another user level thread package named FSU Pthreads (see http://moss.csc.ncsu.edu/~mueller/pthreads/). This implementation is being used for the SCO port.
    See the thr_lock.c and
    thr_alarm.c programs in the
    mysys directory for some tests/examples of
    these problems.
  
Both the server and the client need a working C++ compiler. We use gcc on many platforms. Other compilers that are known to work are SPARCworks, Sun Forte, Irix cc, HP-UX aCC, IBM AIX xlC_r), Intel ecc/icc and Compaq cxx).
To compile only the client use ./configure --without-server.
There is currently no support for only compiling the server, nor is it likely to be added unless someone has a good reason for it.
    If you want/need to change any Makefile or the
    configure script you also need GNU Automake and Autoconf. See
    Section 2.8.3, “Installing from the Development Source Tree”.
  
All steps needed to remake everything from the most basic files.
/bin/rm */.deps/*.P /bin/rm -f config.cache aclocal autoheader aclocal automake autoconf ./configure --with-debug=full --prefix='your installation directory' # The makefiles generated above need GNU make 3.75 or newer. # (called gmake below) gmake clean all install init-db
If you run into problems with a new port, you may have to do some debugging of MySQL! See Section E.1, “Debugging a MySQL Server”.
    Note: Before you start debugging
    mysqld, first get the test programs
    mysys/thr_alarm and
    mysys/thr_lock to work. This ensures that your
    thread installation has even a remote chance to work!
  
      If you are using some functionality that is very new in MySQL, you
      can try to run mysqld with the
      --skip-new (which disables all new, potentially
      unsafe functionality) or with --safe-mode which
      disables a lot of optimization that may cause problems. See
      Section A.4.2, “What to Do If MySQL Keeps Crashing”.
    
      If mysqld doesn't want to start, you should
      verify that you don't have any my.cnf files
      that interfere with your setup! You can check your
      my.cnf arguments with mysqld
      --print-defaults and avoid using them by starting with
      mysqld --no-defaults ....
    
If mysqld starts to eat up CPU or memory or if it “hangs,” you can use mysqladmin processlist status to find out if someone is executing a query that takes a long time. It may be a good idea to run mysqladmin -i10 processlist status in some window if you are experiencing performance problems or problems when new clients can't connect.
The command mysqladmin debug dumps some information about locks in use, used memory and query usage to the MySQL log file. This may help solve some problems. This command also provides some useful information even if you haven't compiled MySQL for debugging!
      If the problem is that some tables are getting slower and slower
      you should try to optimize the table with OPTIMIZE
      TABLE or myisamchk. See
      Chapter 5, Database Administration. You should also check
      the slow queries with EXPLAIN.
    
You should also read the OS-specific section in this manual for problems that may be unique to your environment. See Section 2.12, “Operating System-Specific Notes”.
        If you have some very specific problem, you can always try to
        debug MySQL. To do this you must configure MySQL with the
        --with-debug or the
        --with-debug=full option. You can check whether
        MySQL was compiled with debugging by doing: mysqld
        --help. If the --debug flag is listed
        with the options then you have debugging enabled.
        mysqladmin ver also lists the
        mysqld version as mysql ...
        --debug in this case.
      
If you are using gcc or egcs, the recommended configure line is:
CC=gcc CFLAGS="-O2" CXX=gcc CXXFLAGS="-O2 -felide-constructors \ -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql \ --with-debug --with-extra-charsets=complex
        This avoids problems with the libstdc++
        library and with C++ exceptions (many compilers have problems
        with C++ exceptions in threaded code) and compile a MySQL
        version with support for all character sets.
      
        If you suspect a memory overrun error, you can configure MySQL
        with --with-debug=full, which installs a memory
        allocation (SAFEMALLOC) checker. However,
        running with SAFEMALLOC is quite slow, so if
        you get performance problems you should start
        mysqld with the
        --skip-safemalloc option. This disables the
        memory overrun checks for each call to
        malloc() and free().
      
        If mysqld stops crashing when you compile it
        with --with-debug, you probably have found a
        compiler bug or a timing bug within MySQL. In this case, you can
        try to add -g to the CFLAGS
        and CXXFLAGS variables above and not use
        --with-debug. If mysqld
        dies, you can at least attach to it with gdb
        or use gdb on the core file to find out what
        happened.
      
        When you configure MySQL for debugging you automatically enable
        a lot of extra safety check functions that monitor the health of
        mysqld. If they find something
        “unexpected,” an entry is written to
        stderr, which mysqld_safe
        directs to the error log! This also means that if you are having
        some unexpected problems with MySQL and are using a source
        distribution, the first thing you should do is to configure
        MySQL for debugging! (The second thing is to send mail to a
        MySQL mailing list and ask for help. See
        Section 1.7.1, “MySQL Mailing Lists”. If you believe that you have
        found a bug, please use the instructions at
        Section 1.8, “How to Report Bugs or Problems”.
      
        In the Windows MySQL distribution, mysqld.exe
        is by default compiled with support for trace files.
      
If the mysqld server doesn't start or if you can cause it to crash quickly, you can try to create a trace file to find the problem.
        To do this, you must have a mysqld that has
        been compiled with debugging support. You can check this by
        executing mysqld -V. If the version number
        ends with -debug, it's compiled with support
        for trace files. (On Windows, the debugging server is named
        mysqld-debug rather than
        mysqld as of MySQL 4.1.)
      
        Start the mysqld server with a trace log in
        /tmp/mysqld.trace on Unix or
        C:\mysqld.trace on Windows:
      
shell> mysqld --debug
        On Windows, you should also use the
        --standalone flag to not start
        mysqld as a service. In a console window, use
        this command:
      
C:\> mysqld-debug --debug --standalone
        After this, you can use the mysql.exe
        command-line tool in a second console window to reproduce the
        problem. You can stop the mysqld server with
        mysqladmin shutdown.
      
Note that the trace file become very big! If you want to generate a smaller trace file, you can use debugging options something like this:
mysqld --debug=d,info,error,query,general,where:O,/tmp/mysqld.trace
This only prints information with the most interesting tags to the trace file.
If you make a bug report about this, please only send the lines from the trace file to the appropriate mailing list where something seems to go wrong! If you can't locate the wrong place, you can ftp the trace file, together with a full bug report, to ftp://ftp.mysql.com/pub/mysql/upload/ so that a MySQL developer can take a look at it.
The trace file is made with the DBUG package by Fred Fish. See Section E.3, “The DBUG Package”.
On most systems you can also start mysqld from gdb to get more information if mysqld crashes.
        With some older gdb versions on Linux you
        must use run --one-thread if you want to be
        able to debug mysqld threads. In this case,
        you can only have one thread active at a time. We recommend you
        to upgrade to gdb 5.1 ASAP as thread debugging works much better
        with this version!
      
NTPL threads (the new thread library on Linux) may cause problems while running mysqld under gdb. Some symptoms are:
            mysqld hangs during startup (before it
            writes ready for connections).
          
            mysqld crashes during a
            pthread_mutex_lock() or
            pthread_mutex_unlock() call.
          
In this case, you should set the following environment variable in the shell before starting gdb:
LD_ASSUME_KERNEL=2.4.1 export LD_ASSUME_KERNEL
        When running mysqld under
        gdb, you should disable the stack trace with
        --skip-stack-trace to be able to catch
        segfaults within gdb.
      
        In MySQL 4.0.14 and above you should use the
        --gdb option to mysqld. This installs an
        interrupt handler for SIGINT (needed to stop
        mysqld with ^C to set
        breakpoints) and disable stack tracing and core file handling.
      
        It's very hard to debug MySQL under gdb if
        you do a lot of new connections the whole time as
        gdb doesn't free the memory for old threads.
        You can avoid this problem by starting mysqld
        with --thread_cache_size='max_connections+1'.
        In most cases just using --thread_cache_size=5'
        helps a lot!
      
        If you want to get a core dump on Linux if
        mysqld dies with a SIGSEGV signal, you can
        start mysqld with the
        --core-file option. This core file can be used
        to make a backtrace that may help you find out why
        mysqld died:
      
shell> gdb mysqld core
gdb>   backtrace full
gdb>   exit
See Section A.4.2, “What to Do If MySQL Keeps Crashing”.
        If you are using gdb 4.17.x or above on
        Linux, you should install a .gdb file, with
        the following information, in your current directory:
      
set print sevenbit off handle SIGUSR1 nostop noprint handle SIGUSR2 nostop noprint handle SIGWAITING nostop noprint handle SIGLWP nostop noprint handle SIGPIPE nostop handle SIGALRM nostop handle SIGHUP nostop handle SIGTERM nostop noprint
If you have problems debugging threads with gdb, you should download gdb 5.x and try this instead. The new gdb version has very improved thread handling!
Here is an example how to debug mysqld:
shell> gdb /usr/local/libexec/mysqld
gdb> run
...
backtrace full # Do this when mysqld crashes
Include the above output in a bug report, which you can file using the instructions in Section 1.8, “How to Report Bugs or Problems”.
        If mysqld hangs you can try to use some
        system tools like strace or
        /usr/proc/bin/pstack to examine where
        mysqld has hung.
      
strace /tmp/log libexec/mysqld
        If you are using the Perl DBI interface, you
        can turn on debugging information by using the
        trace method or by setting the
        DBI_TRACE environment variable.
      
        On some operating systems, the error log contains a stack trace
        if mysqld dies unexpectedly. You can use this
        to find out where (and maybe why) mysqld
        died. See Section 5.12.1, “The Error Log”. To get a stack trace, you
        must not compile mysqld with the
        -fomit-frame-pointer option to gcc. See
        Section E.1.1, “Compiling MySQL for Debugging”.
      
If the error file contains something like the following:
mysqld got signal 11; The manual section 'Debugging a MySQL server' tells you how to use a stack trace and/or the core file to produce a readable backtrace that may help in finding out why mysqld died Attempting backtrace. You can use the following information to find out where mysqld died. If you see no messages after this, something went terribly wrong... stack range sanity check, ok, backtrace follows 0x40077552 0x81281a0 0x8128f47 0x8127be0 0x8127995 0x8104947 0x80ff28f 0x810131b 0x80ee4bc 0x80c3c91 0x80c6b43 0x80c1fd9 0x80c1686
you can find where mysqld died by doing the following:
            Copy the preceding numbers to a file, for example
            mysqld.stack.
          
Make a symbol file for the mysqld server:
nm -n libexec/mysqld > /tmp/mysqld.sym
            Note that most MySQL binary distributions (except for the
            "debug" packages, where this information is included inside
            of the binaries themselves) ship with the above file, named
            mysqld.sym.gz. In this case, you can
            simply unpack it by doing:
          
gunzip < bin/mysqld.sym.gz > /tmp/mysqld.sym
            Execute resolve_stack_dump -s /tmp/mysqld.sym -n
            mysqld.stack.
          
This prints out where mysqld died. If this doesn't help you find out why mysqld died, you should make a bug report and include the output from the above command with the bug report.
Note however that in most cases it does not help us to just have a stack trace to find the reason for the problem. To be able to locate the bug or provide a workaround, we would in most cases need to know the query that killed mysqld and preferable a test case so that we can repeat the problem! See Section 1.8, “How to Report Bugs or Problems”.
        Note that before starting mysqld with
        --log you should check all your tables with
        myisamchk. See
        Chapter 5, Database Administration.
      
        If mysqld dies or hangs, you should start
        mysqld with --log. When
        mysqld dies again, you can examine the end of
        the log file for the query that killed
        mysqld.
      
        If you are using --log without a file name, the
        log is stored in the database directory as
        host_name.log
        You can also try the command EXPLAIN on all
        SELECT statements that takes a long time to
        ensure that mysqld is using indexes properly.
        See Section 7.2.1, “Optimizing Queries with EXPLAIN”.
      
        You can find the queries that take a long time to execute by
        starting mysqld with
        --log-slow-queries. See
        Section 5.12.4, “The Slow Query Log”.
      
        If you find the text mysqld restarted in the
        error log file (normally named
        hostname.err) you probably have found a
        query that causes mysqld to fail. If this
        happens, you should check all your tables with
        myisamchk (see
        Chapter 5, Database Administration), and test the queries
        in the MySQL log files to see whether one fails. If you find
        such a query, try first upgrading to the newest MySQL version.
        If this doesn't help and you can't find anything in the
        mysql mail archive, you should report the bug
        to a MySQL mailing list. The mailing lists are described at
        http://lists.mysql.com/, which also has links to
        online list archives.
      
        If you have started mysqld with
        myisam-recover, MySQL automatically checks
        and tries to repair MyISAM tables if they are
        marked as 'not closed properly' or 'crashed'. If this happens,
        MySQL writes an entry in the hostname.err
        file 'Warning: Checking table ...' which is
        followed by Warning: Repairing table if the
        table needs to be repaired. If you get a lot of these errors,
        without mysqld having died unexpectedly just
        before, then something is wrong and needs to be investigated
        further. See Section 5.2.1, “mysqld Command Options”.
      
        It is not a good sign if mysqld did die
        unexpectedly, but in this case, you should not investigate the
        Checking table... messages, but instead try
        to find out why mysqld died.
      
If you get corrupted tables or if mysqld always fails after some update commands, you can test whether this bug is reproducible by doing the following:
Take down the MySQL daemon (with mysqladmin shutdown).
Make a backup of the tables (to guard against the very unlikely case that the repair does something bad).
            Check all tables with myisamchk -s
            database/*.MYI. Repair any wrong tables with
            myisamchk -r
            database/table.MYI.
          
Make a second backup of the tables.
Remove (or move away) any old log files from the MySQL data directory if you need more space.
            Start mysqld with
            --log-bin. See
            Section 5.12.3, “The Binary Log”. If you want to find a query
            that crashes mysqld, you should use
            --log --log-bin.
          
            When you have gotten a crashed table, stop the
            mysqld server.
          
Restore the backup.
            Restart the mysqld server
            without
            --log-bin
          
            Re-execute the commands with mysqlbinlog
            update-log-file | mysql. The update log is saved
            in the MySQL database directory with the name
            hostname-bin.#.
          
            If the tables are corrupted again or you can get
            mysqld to die with the above command, you
            have found reproducible bug that should be easy to fix! FTP
            the tables and the binary log to
            ftp://ftp.mysql.com/pub/mysql/upload/ and report it in our bugs
            database using the instructions given in
            Section 1.8, “How to Report Bugs or Problems”. (Please note that the
            /pub/mysql/upload/ FTP directory is not
            listable, so you'll not see what you've uploaded in your FTP
            client.) If you are a support customer, you can use the
            MySQL Customer Support Center
            https://support.mysql.com/ to alert the MySQL
            team about the problem and have it fixed as soon as
            possible.
          
        You can also use the script mysql_find_rows
        to just execute some of the update statements if you want to
        narrow down the problem.
      
      To be able to debug a MySQL client with the integrated debug
      package, you should configure MySQL with
      --with-debug or
      --with-debug=full. See
      Section 2.8.2, “Typical configure Options”.
    
      Before running a client, you should set the
      MYSQL_DEBUG environment variable:
    
shell>MYSQL_DEBUG=d:t:O,/tmp/client.traceshell>export MYSQL_DEBUG
      This causes clients to generate a trace file in
      /tmp/client.trace.
    
If you have problems with your own client code, you should attempt to connect to the server and run your query using a client that is known to work. Do this by running mysql in debugging mode (assuming that you have compiled MySQL with debugging on):
shell> mysql --debug=d:t:O,/tmp/client.trace
This provides useful information in case you mail a bug report. See Section 1.8, “How to Report Bugs or Problems”.
      If your client crashes at some 'legal' looking code, you should
      check that your mysql.h include file matches
      your MySQL library file. A very common mistake is to use an old
      mysql.h file from an old MySQL installation
      with new MySQL library.
    
The MySQL server and most MySQL clients are compiled with the DBUG package originally created by Fred Fish. When you have configured MySQL for debugging, this package makes it possible to get a trace file of what the program is debugging. See Section E.1.2, “Creating Trace Files”.
      This section summaries the argument values that you can specify in
      debug options on the command line for MySQL programs that have
      been built with debugging support. For more information about
      programming with the DBUG package, see the DBUG manual in the
      dbug directory of MySQL source distributions.
      It's best to use a recent distribution for MySQL 5.0
      to get the most updated DBUG manual.
    
      You use the debug package by invoking a program with the
      --debug="..." or the -#...
      option.
    
      Most MySQL programs have a default debug string that is used if
      you don't specify an option to --debug. The
      default trace file is usually
      /tmp/program_name.trace on Unix and
      \program_name.trace on Windows.
    
The debug control string is a sequence of colon-separated fields as follows:
<field_1>:<field_2>:...:<field_N>
      Each field consists of a mandatory flag character followed by an
      optional ‘,’ and comma-separated
      list of modifiers:
    
flag[,modifier,modifier,...,modifier]
The currently recognized flag characters are:
| Flag | Description | 
| d | Enable output from DBUG_<N> macros for the current state. May be followed by a list of keywords which selects output only for the DBUG macros with that keyword. An empty list of keywords implies output for all macros. | 
| D | Delay after each debugger output line. The argument is the number of
              tenths of seconds to delay, subject to machine
              capabilities. For example, -#D,20specifies a delay of two seconds. | 
| f | Limit debugging, tracing, and profiling to the list of named functions.
              Note that a null list disables all functions. The
              appropriate dortflags must still be given; this flag only limits their
              actions if they are enabled. | 
| F | Identify the source file name for each line of debug or trace output. | 
| i | Identify the process with the PID or thread ID for each line of debug or trace output. | 
| g | Enable profiling. Create a file called dbugmon.outcontaining information that can be used to profile the
              program. May be followed by a list of keywords that select
              profiling only for the functions in that list. A null list
              implies that all functions are considered. | 
| L | Identify the source file line number for each line of debug or trace output. | 
| n | Print the current function nesting depth for each line of debug or trace output. | 
| N | Number each line of debug output. | 
| o | Redirect the debugger output stream to the specified file. The default
              output is stderr. | 
| O | Like o, but the file is really flushed between each
              write. When needed, the file is closed and reopened
              between each write. | 
| p | Limit debugger actions to specified processes. A process must be
              identified with the DBUG_PROCESSmacro
              and match one in the list for debugger actions to occur. | 
| P | Print the current process name for each line of debug or trace output. | 
| r | When pushing a new state, do not inherit the previous state's function nesting level. Useful when the output is to start at the left margin. | 
| S | Do function _sanity(_file_,_line_)at each debugged
              function until_sanity()returns
              something that differs from 0. (Mostly used withsafemallocto find memory leaks) | 
| t | Enable function call/exit trace lines. May be followed by a list (containing only one modifier) giving a numeric maximum trace level, beyond which no output occurs for either debugging or tracing macros. The default is a compile time option. | 
      Some examples of debug control strings that might appear on a
      shell command line (the -# is typically used to
      introduce a control string to an application program) are:
    
-#d:t -#d:f,main,subr1:F:L:t,20 -#d,input,output,files:n -#d:t:i:O,\\mysqld.trace
      In MySQL, common tags to print (with the d
      option) are enter, exit,
      error, warning,
      info, and loop.
    
I have tried to use the RTS thread packages with MySQL but stumbled on the following problems:
They use old versions of many POSIX calls and it is very tedious to make wrappers for all functions. I am inclined to think that it would be easier to change the thread libraries to the newest POSIX specification.
      Some wrappers are currently written. See
      mysys/my_pthread.c for more info.
    
At least the following should be changed:
      pthread_get_specific should use one argument.
      sigwait should take two arguments. A lot of
      functions (at least pthread_cond_wait,
      pthread_cond_timedwait()) should return the
      error code on error. Now they return -1 and set
      errno.
    
      Another problem is that user-level threads use the
      ALRM signal and this aborts a lot of functions
      (read, write,
      open...). MySQL should do a retry on interrupt
      on all of these but it is not that easy to verify it.
    
The biggest unsolved problem is the following:
      To get thread-level alarms I changed
      mysys/thr_alarm.c to wait between alarms with
      pthread_cond_timedwait(), but this aborts with
      error EINTR. I tried to debug the thread
      library as to why this happens, but couldn't find any easy
      solution.
    
If someone wants to try MySQL with RTS threads I suggest the following:
Change functions MySQL uses from the thread library to POSIX. This shouldn't take that long.
          Compile all libraries with the
          -DHAVE_rts_threads.
        
          Compile thr_alarm.
        
          If there are some small differences in the implementation,
          they may be fixed by changing
          my_pthread.h and
          my_pthread.c.
        
          Run thr_alarm. If it runs without any
          “warning,” “error,” or aborted
          messages, you are on the right track. Here is a successful run
          on Solaris:
        
Main thread: 1 Thread 0 (5) started Thread: 5 Waiting process_alarm Thread 1 (6) started Thread: 6 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 1 (1) sec Thread: 6 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 2 (2) sec Thread: 6 Simulation of no alarm needed Thread: 6 Slept for 0 (3) sec Thread: 6 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 4 (4) sec Thread: 6 Waiting process_alarm thread_alarm Thread: 5 Slept for 10 (10) sec Thread: 5 Waiting process_alarm process_alarm thread_alarm Thread: 6 Slept for 5 (5) sec Thread: 6 Waiting process_alarm process_alarm ... thread_alarm Thread: 5 Slept for 0 (1) sec end
MySQL is very dependent on the thread package used. So when choosing a good platform for MySQL, the thread package is very important.
There are at least three types of thread packages:
User threads in a single process. Thread switching is managed with alarms and the threads library manages all non-thread-safe functions with locks. Read, write and select operations are usually managed with a thread-specific select that switches to another thread if the running threads have to wait for data. If the user thread packages are integrated in the standard libs (FreeBSD and BSDI threads) the thread package requires less overhead than thread packages that have to map all unsafe calls (MIT-pthreads, FSU Pthreads and RTS threads). In some environments (for example, SCO), all system calls are thread-safe so the mapping can be done very easily (FSU Pthreads on SCO). Downside: All mapped calls take a little time and it's quite tricky to be able to handle all situations. There are usually also some system calls that are not handled by the thread package (like MIT-pthreads and sockets). Thread scheduling isn't always optimal.
User threads in separate processes. Thread switching is done by the kernel and all data are shared between threads. The thread package manages the standard thread calls to allow sharing data between threads. LinuxThreads is using this method. Downside: Lots of processes. Thread creating is slow. If one thread dies the rest are usually left hanging and you must kill them all before restarting. Thread switching is somewhat expensive.
Kernel threads. Thread switching is handled by the thread library or the kernel and is very fast. Everything is done in one process, but on some systems, ps may show the different threads. If one thread aborts, the whole process aborts. Most system calls are thread-safe and should require very little overhead. Solaris, HP-UX, AIX and OSF/1 have kernel threads.
In some systems kernel threads are managed by integrating user level threads in the system libraries. In such cases, the thread switching can only be done by the thread library and the kernel isn't really “thread aware.”