START-INFO-DIR-ENTRY * mysql: (mysql). *MySQL* documentation. END-INFO-DIR-ENTRY This is a manual for *MySQL*. This version is about the 3.21.30 version of *MySQL*. For a *3.20* version see the relevant distribution. General Information about *MySQL* ********************************* This is the *MySQL* reference manual. This version documents the 3.21.30 version of *MySQL*. *MySQL* is a basically free SQL database server. *Note Licensing and Support::. The latest information about *MySQL* is found at the *MySQL* Home page (http://www.tcx.se) To see what it can do. *Note Features::. For installation instructions *Note Installing::. For tips on how to port *MySQL* to new machines/operating systems *Note Porting::. If you have any suggestions concerning additions or corrections to this manual, please send them to the *MySQL* mailing list with the following subject line; `documentation suggestion: [Insert Topic Here]'. *Note Mailing-list::. *Note Upgrading-from-3.20::, for information about upgrading from a 3.20 release. For examples of SQL and benchmarking information see the `bench' directory. For future plans *Note Todo::. A history of new features/bug fixes *Note News::. For the currently known bugs/misfeatures (known errors) *Note Bugs::. For A list of all the contributors to this product *Note Credits::. *IMPORTANT:* Send bug (error) reports, questions and comments to the mailing list at Please use the `mysqlbug' script when posting bug reports or questions about *MySQL*. `mysqlbug' will gather some information about your system and start your editor with a form in which you can describe your problem. Bug reports might be silently ignored by the *MySQL* maintainers if there is not a good reason included in the report as to why mysqlbug has not been used. A report that says 'MySQL does not work for me. Why?' is not consider a valid bug report. The mysqlbug script can be found in the `scripts' directory in the distribution, that is `there-you-installed-mysql/scripts'. What is *MySQL*? ================ *MySQL* is a SQL (Structured Query Language) database server. SQL is the most popular database language in the world. *MySQL* is a client server implementation that consists of a server daemon `mysqld' and many different client programs/libraries. The main goals of *MySQL* are speed and robustness. The base upon which *MySQL* is built is a set of routines that have been used in a highly demanding production environment for many years. While *MySQL* is still in development it already offers a rich and highly useful function set. The official way to pronounce *MySQL* is 'My Ess Que Ell' (Not MY-SEQUEL). About this manual ================= This manual is currently available in TeXInfo, Raw text, Info and HTML versions. A PostScript version as available do download separately because of its size. The primary document is the TeXInfo file. The HTML version is automatically produced with a modified `texi2html'. The ASCII and info version are produced with `makeinfo'. The Postscript version is produced using `texi2dvi' and `dvips'. This manual is written and maintained by David Axmark, Michael (Monty) Widenius and Kim Aldale. For other contributors *Note Contrib::. History of *MySQL* ================== We once started off with the intention to use `mSQL' to connect to our own fast low level (ISAM) tables. However, after some testing we came to the conclusion that `mSQL' was not fast or flexible enough for our needs. This resulted in a new SQL interface to our database but with almost the same API interface as `mSQL'. This API was chosen to ease porting of third-party code. It is not perfectly clear where the name *MySQL* derives from. Our base directory and a large amount of our libraries and tools have had the prefix 'my' for well over 10 years. However, Monty's daughter (some years younger) is also named My. So which of the two gave its name to *MySQL* is still a mystery, even for us. The main features of *MySQL* ============================ * Fully multi-threaded using kernel threads. That means that it easily can use multiple CPUs if available. * C, C++, JAVA, Perl, Python and TCL API's. *Note Clients:: * Works on a lot of different platforms. *Note Which OS::. * Lots of column types like: signed/unsigned integers 1,2,3,4 and 8 bytes long, `FLOAT', `DOUBLE', `CHAR', `VARCHAR', `TEXT', `BLOB', `DATE', `SET' and `ENUM' types. *Note Column types:: * Very fast joins using a optimised one-sweep multi-join. * Full function support in the SELECT and WHERE parts. Example: `select column1 + column2 from table where column1/column2 > 0' * SQL functions are implemented through a very optimised class library and should be as fast as they can get! Usually there shouldn't be any memory allocation at all after the query initialisation. * Full support for SQL `GROUP BY' and `ORDER BY'. Support for group functions (`COUNT', `AVG', `SUM', `MAX' and `MIN'). * Support for `LEFT OUTER JOIN' with ANSI SQL and ODBC syntax. * A privilege and password system which is very flexible and secure. Allows host based verification. * Secure passwords since all password traffic on the net is encrypted. * ODBC Open-DataBase-Connectivity for Windows95 (with source). All ODBC 2.5 functions and lots of others. So you can for example use Access to connect to your *MySQL* server. *Note ODBC:: * Very fast B-tree disk tables with index compression. * 16 indexes/table. Each index may consist of 1 to 15 columns/parts of columns. Max index length is 256 bytes (but may be changed when compiling *MySQL*. An index may be a prefix of a CHAR field. * Fixed and variable length records. * In memory hash tables which are used as temporary tables. * Handles large databases (we are using *MySQL* with some databases that contain 50,000,000 records). * All columns have default values. One can always use INSERT on any subset of columns. * Uses GNU `autoconf' for portability. * Written in C and C++. Tested with a broad range of different compilers. * A very fast thread-based memory allocation system. * No memory leaks. Tested with a commercial memory leakage detector (`purify'). * A very fast table check,optimize and repair utility. *Note isamchk:: * All data saved in ISO8859_1 format. All comparisons for normal string columns are case insensitive. * Full ISO8859_1 (Latin1) support. For example Scandinavian едц is allowed in table and column names. * Sorts by ISO8859_1 Latin1 (the Swedish way at the moment). It is possible to change this in the source by adding new sort order arrays. To see a example of a very advanced sorting, look at the Czeck sorting code. * Alias on tables and columns as in the SQL92 standard. * `DELETE', `INSERT', `REPLACE', and `UPDATE' returns how many rows were affected. * Function names do not clash with table or column names. For example ABS is a valid column name. The only restriction is that space is not allowed between a function name and the '(' when using functions. *Note Reserved words:: * All *MySQL* commands have `--help' or `-?' for help. * The server currently supports error messages to clients in many languages. *Note Languages::. * The clients use a TCP connection or Unix socket when connecting to the *MySQL* server. * User commands as `show tables', `SHOW INDEX FROM table' and `show columns from table' General SQL information and tutorials ===================================== There is one SQL tutor on the net at `http://w3.one.net/~jhoffman/sqltut.htm' This one has been recommended by a lot of people on the *MySQL* mailing list. Judith S. Bowman, Sandra L. Emerson and Marcy Darnovsky "The Practical SQL Handbook: Using Structured Query Language" Second Edition Addison Wesley ISBN 0-201-62623-3 http://www.awl.com And another book also recommended by people on the *MySQL* mailing list. Understanding SQL ISBN 0-89588-644-8 Publisher Sybex 510 523 8233 Alameda CA USA Useful MySQL-related links ========================== Some web development tools which support *MySQL* ------------------------------------------------ * PHP: A server-side HTML-embedded scripting language (http://www.php.net) * *MySQL* + PHP demos (http://www.wernhart.priv.at/php/) * WWW-SQL: Display databases information (http://www.daa.com.au/~james/www-sql/) * Minivend: A Web shopping cart (http://www.minivend.com/minivend/) * HeiTML: A server-side extension of HTML and a 4GL language at the same time (http://www.heitml.com) * Metahtml: A Dynamic Programming Language for WWW Applications (http://www.metahtml.com/) * VelocityGen for Perl and TCL (http://www.binevolve.com/) * Hawkeye Internet Server Suite (http://hawkeye.net) Web servers with *MySQL* tools ------------------------------ * An Apache authentication module (http://bourbon.netvision.net.il/mysql/mod_auth_mysql/) * The Roxen Challenger Web server (http://www.roxen.com/) Examples -------- bullet A Contact Database using MySQL and PHP (http://www.webtechniques.com/features/1998/01/note/note.shtml) Other *MySQL* related links. ---------------------------- * Comercial Web defect tracking system (http://www.open.com.au/products.html) * PTS - Project Tracking System (http://www.stonekeep.com/pts/) * Support for BIND (The Internet Domain Name Server) (http://www.seawood.org/msql_bind/) * A REXX interface to SQL databases (http://www.lightlink.com/hessling/rexxsql.html) * Registry of Web providers who support *MySQL* (http://www.wix.com/mysql-hosting) * TCL interface (http://www.binevolve.com/~tdarugar/tcl-sql/) * Patch for mSQL TCL (http://www.gagme.com/mysql) * Full-text search engine using *MySQL* (http://www.pi.net/~hverbeek/mysql/) * WDB; Web browser as a universal front end to databases (http://www.lava.net/beowulf/programming/wdb/) * EasySQL; An ODBC like driver manager (http://www.amsoft.ru/easysql/) * Network Database Connection For Linux (http://www.fastflow.com/) * ExportSQL A script to export data from Access (http://www.cynergi.net/non-secure/exportsql/) * SAL (Scientific Applications on Linux) *MySQL* entry (http://SAL.KachinaTech.COM/H/1/MYSQL.html) * *MySQL* Apps and Utilities Listing (http://www.cgishop.com/bin/mysqllist) * The *MySQL* reference manual in Adobe PDF format (http://www.luth.se/~goggi/proj/mysql/man/mysql.pdf) * A consulting company which mentions *MySQL* in the right company. (http://www.infotech-nj.com/itech/index.shtml) * PMP Computer Solutions. Database developers using mySQL and mSQL (http://www.pmpcs.com/) * Airborne Early Warning Association (http://www.aewa.org) * MySQL binding to Free Pascal (http://tfdec1.fys.kuleuven.ac.be/~michael/fpc-linux/mysql) General database links. ----------------------- * Database Jump Site (http://www.pcslink.com/~ej/dbweb.html) * The JDBC database access API (http://java.sun.com/products/jdbc/) * Homepage of the webdb-l (Web Databases) mailing list. (http://black.hole-in-the.net/guy/webdb/) * perl DBI/DBD modules homepage (http://www.hermetica.com/technologia/DBI/) There are also many web pages that use *MySQL*. *Note Users::. Send any additions to this list to . What are stored procedures and triggers and so on? ================================================== A stored procedure is a set of SQL commands that can be stored and compiled in the server. After this, the client doesn't have to issue the whole query but can refer to the stored procedure. This gives some more speed because the query only has to be parsed once and there is less data that has to be sent between the server and the client. You can also raise the conceptual level by having libraries of functions in the server. A trigger is a stored procedure that is invoked when something happens. For example one can install a stored procedure that checks every delete to a transaction table and does an automatic delete on the corresponding customer when all his transactions are deleted. To see when *MySQL* might get these functions *Note Todo::. *MySQL* mailing lists and how to ask questions/give error (bug) reports *********************************************************************** Subscribing to/un-subscribing from the *MySQL* mailing list. ============================================================ Requests to be added or dropped from the *MySQL* list should be sent to the electronic mail address . Sending a one line message saying either `subscribe mysql' or `un-subscribe mysql' will suffice. If your reply address is not valid you may use `subscribe mysql your@address.your-domain' or `un-subscribe mysql your@address.your-domain'. Please *do not* send mail about [un]subscribing to since any mail sent to this address is automatically forwarded to hundreds of other users. Your local site may have many subscribers to . In that case, it may have a local mailing list, so that a single message from `tcx.se' is sent to the site and propagated to the local list. In such cases, please contact your system administrator to be added to or dropped from the local list. Mail to `mdomo' is handled automatically by majordomo. The following mailinglists exists: `mysql-announce' This is form announcement of new versions of *MySQL* and related programs. This is a low volume list that we think all *MySQL* users should be on. `mysql' The main list for general *MySQL* discussion. Please note that some things should go to the specialized lists. It you post to the wrong list you may not get a answer! `mysql-digest' The above list in digest form. That means that tou get all messages in one mail once a day. `mysql-Java' Discussion about MySQL and JAVA. Mostly about the JDBC drivers. `mysql-win32' All things concerning MySQL on Microsoft operating system like Windows/NT. `myodbc' All things concerning connection to MySQL with ODBC. `msql-mysql-modules' A list about the Perl support in MySQL. `msql-mysql-modules-digest' A digest version of the above. You subscribe/unsubscribe to all lists in the same way as described above. Just exchange `mysql' with the list name. Asking questions or reporting bugs. =================================== Before you ask a question on the mailing list, it is a good idea to check this manual. If you can't find an answer here, check with your local *MySQL* expert. If you still can't find an answer to your question go ahead and read the next section about how to send mail to . I think I have found a bug. What information do you need to help me? ==================================================================== If you can, please use the `mysqlbug' script that can be found in the scripts directory in the distribution. If that is not possible, remember to specify (if relevant) the following. Note that it is possible to answer a letter with too much information but not one with too little. You should always use `mysqlbug' if your question is anyway related to a *MySQL* version you are using! mysqlbug should automaticly finds most of the following information, but if something important missing please include this in your question! 1. State which version of *MySQL* you are using (for example mysql-3.21..tgz). You can find out which version you are running by typing `mysqladmin version'. 2. The manufacturer and model of machine you are working on. 3. The operating system. For most operating systems you can get this from `uname -a'. 4. Sometimes the amount of memory (real and virtual) is also relevant. 5. Write in the mail that you have checked the reference manual and mail archive so others know that you have tried to solve your problem yourself. 6. If this is a bug when compiling: Include the exact error messages and also a few lines around the offending code in the file from which you got the error. 7. If this is a run-time bug, please describe exactly how you got the error. If you can include a test program, with tables, which shows the error you will probably get a more explicit answer. 8. f the you can't produce a test case in a few rows or if the the test table is too big to be mailed to everyone (more than 10 rows) you should make a mysqldump of your tables and make a README that describes your problem. Tar and gzip or zip the files and ftp the archive to ftp://www.tcx.se/pub/mysql/hidden. Send after this a short description of the problem to 9. If the questions is related to the privilege system, please include the output of mysqlaccess, the output of 'mysqladmin reload' and and all error messages you get when trying to connect ! You should do the test in the above order ! If you are a support customer, please post the bug report to the specified mailing list for higher priority treatment. When answers are sent to you individually and not to the mailing list, it is considered good etiquette to summarise the answers and mail them to the mailing list. *MySQL* keeps crashing ---------------------- Since it is very hard to now why something crashing please do one of the following things. First try to check if thigs that work for other crash for you: * Have you tried the benchmarks? This should test MySQL rather well. You can also add code that simulates your application! * Try also fork_test.pl and fork2_test.pl * Check the reference manual about debugging mysqld. * Recompile *MySQL* with the `--with-debug' switch to configure. This will include a safe memory allocator that can find some errors. This also gives a lot of output about what is happening. * Use mysqld -log and try to find if it some specific query that kills it. 95% of all bugs is related to some specific query! * Have you applied the latest patches for your Operating System ? * Use -skip-locking * Have you tried 'mysqladmin proc' when it 'dies' ? * Put in some window the following command to output statistics: mysqladmin -i 5 status * 1. Start mysqld with gdb (or another debugger). 2. Run your test scripts. 3. Do `back' (or the backtrace command in your debugger) when `mysqld' core dumps. * Try to simulate your application with a perl script to force *MySQL* to crash/misbehave. * Or send a normal bug report. *Note Bug reports::. But be even more detailed than normally. Since *MySQL* works for a lot of people it may that the crash comes from something that only exists on your computer. For example, a system library error. Guidelines for answering questions on the mailing list. ======================================================= Try to make your answer broad enough that people other than the original poster may benefit from it. If you consider your answer to have broad interest, you may want to post it to the mailing list instead of replying directly to the individual who asked. In such cases, please make sure that your answer is not a duplication of a previous answer. Try to summarise the essential part of the question in your reply, but don't feel obliged to quote the whole question. Licensing or When do I have/want to pay for *MySQL*? **************************************************** Basic licensing issues: * The easiest way to pay for *MySQL* is to use the license form at TcX's secure server at `https://www.tcx.se/license.htmy' * We hope everybody understands that you only have to pay if you are selling *MySQL* directly or selling a product which includes the *MySQL* server. You may not include *MySQL* in a distribution if you charge for some part of it. For internal use you do not have to pay us if you do not want to. * The client code is in the Public Domain or under the GPL (readline). You do not need a license to include client code in commercial programs. * We may add some additional functionality in the commercial version. The likely test candidate for this is fast compressed read-only databases. The current server includes support to read such databases but not the packing tool. If we get enough revenue from support we will probably release this under the same license as the other stuff. * But if you like *MySQL* and want to encourage further development you are welcome to purchase a license or support. *Note Public::. How much does *MySQL* cost? =========================== For normal use *MySQL* costs nothing. When you sell *MySQL* directly or as a part of another product you have to pay for it. *Note Public::. The client access part of *MySQL* is in the public domain. The command line client includes parts that is under the GNU Public License (readline). These are our current license prices. All prices are in US Dollars. If you pay by credit card, the currency is FIM (Finish Marks) so the prices will differ slightly. Number of licenses Price/Copy Total 1 US $200 US $200 10 pack US $150 US $1500 50 pack US $120 US $6000 For high volume (OEM) purchases the following prices apply: licenses Price/Copy Minimum at Minimum Payment one time 100-1000 $40 100 $4000 1000-2500 $25 200 $5000 2500-5000 $20 400 $8000 The OEM prices require that you act as a middle-man for eventual problems/extension requests from users. We also require that the OEM customer has a support contract. If you have a low-margin high-volume product, you can always talk to us about other terms (for example a percent of the sale price). If you do, please be informative about your product, pricing, market and any other information that may be relevant. How do I get commercial support? ================================ A full-price license includes really basic support. This means that we are trying to answer any relevant question. If the answer is in the documentation, we are going to direct you to the relevant documentation. If you do not have a license/support we will probably not answer at all. If you discover what we consider a real bug, we are likely to fix it in any case. But if you pay for support we will notify you about the fix status instead of just fixing it in a later release. More comprehensive support is sold separately: Types of commercial support --------------------------- Basic email support ................... One year of basic email support costs $200 (USD). It includes: 1. For *MySQL* specific questions that doesn't belong to the *MySQL* mailing list (), you can contact . Remember to give your registration number and expiration date when mailing any list to ensure a quick response. 2. We guaranty a timely answer for your emails. We can't guaranty that we can solve ant problem, but at least you will receive an answer if we can contact you by email. 3. Your suggestions for the further development of *MySQL* will be taken into consideration. By taking email support you have already helped the further development of *MySQL*. If you want to have more input upgrade to a higher level of support. 4. Helping with unexpected problems when installing *MySQL* from a binary distribution on a supported platforms. 5. We will help you with bugs and missing features. All found bugs are fixed for the next *MySQL* release. If the bug is critical for you, we will mail you a patch for it as soon the bug is fixed. Critical bugs always have the highest priority for us, to ensure that they are fixed as soon as possible. 6. This level of support does not cover installing *MySQL* from a source distribution. 7. If you want us to help to optimize your system you have to upgrade to a higher level of support. 8. You are entitled to upgrade to other support options for the difference between the prices. Extended email support ...................... One year of extended email support costs $1000 (USD). Extended basic supports contains everything in basic email support with these additions: 1. Your email will be dealt with before normal email support users and non-registered users. 2. Your suggestions for the further development of *MySQL* will receive strong consideration. Simple extensions that suit the basic goals of *MySQL* are implemented in a matter of days. By taking extended email support you have already helped the further development of *MySQL*. 3. In this we include a binary version of the pack_isam tool that supports fast compressed read only databases (no `BLOB' or `TEXT' types yet). The current server includes support to read such databases but not the packing tool. 4. Typical questions that are covered by extended email support are: * Answering and solving (within reason) questions that relate to (possibly) bugs in *MySQL*. As soon as the bug is found and corrected, we will mail a patch for it. * Helping with unexpected problems when installing *MySQL* from a source/binary distribution on supported platforms. * Questions about missing features and offer hints how to go around them. * How to optimize mysqld for your situation. 5. You are allowed to slightly alter *MySQL* TODO. This will ensure that the features you really need will be implemented sooner than otherwise. 6. You are entitled to upgrade to login support for the difference between the different support prices. Login support ............. One year of email/phone/telnet support costs $2000 (USD). Login supports contains everything in extended basic email support with these additions: 1. Your email will be dealt with even before mails from extended support users. 2. Your suggestions for the further development of *MySQL* will be taken into very high consideration Realistic extensions that can be implemented in a a couple of hours and suits the basic goals of *MySQL* will be implemented as soon as possible. 3. If you have a very specific problem we can try to log in on your system and try to solve it 'in place'. 4. As any database vendor, we can't guaranty that we can rescue any data from crashed tables, but if the worst happens we will help you rescue as much as possible. *MySQL* has proven itself very reliable, but because of outside interference anything is possible. 5. We will give you hints how to optimize your system and your queries. 6. You are allowed to call a *MySQL* developer (in moderation) and discuss your *MySQL* related problems. Extended login support ...................... One year of extended email/phone/telnet support costs $5000 (USD). Extended login supports contains everything in login support with these additions: 1. Your email has the highest possible priority. 2. We will actively examine your system and help you optimize it and your queries. We may also optimize and/or extend *MySQL* to better suite your needs. 3. You may also request special extensions just for you. For example select my_calculation(column1,column2) from database; 4. We will provide a binary version of all important *MySQL* distributions for your system, as long as we can get an account on a similar system. In the worst case we may require access to your system to be able to make a binary version. 5. If you can provide accommodation and pay for traveler fares you can even get a *MySQL* developer to visit you and offer you help with your troubles. The extended login support entitles you to one personal encounter, but we are as always very flexible towards our customers! How do I pay for licenses/support ? =================================== Currently we can take SWIFT payments, cheques or credit cards. Payment should be made to: Postgirot Bank AB 105 06 STOCKHOLM, SWEDEN T.C.X DataKonsult AB BOX 6434 11382 STOCKHOLM, SWEDEN SWIFT address: PGSI SESS Account number: 96 77 06 - 3 Specify: license and/or support and your name and email address. In Europe and Japan you can use EuroGiro (that should be cheaper) to the same account. If you want to pay by cheque make it payable to "Monty Program KB". And mail it to the address below. T.C.X DataKonsult AB BOX 6434 11382 STOCKHOLM, SWEDEN If you want to pay with credit card over the Internet you can use TcX's secure license form (https://www.tcx.se/license.htmy) Who do I contact when I want more information about licensing/support? ====================================================================== For commercial licensing, or if you have any questions about any of the information in this section, please contact: David Axmark Detron HB Kungsgatan 65 B 753 21 UPPSALA SWEDEN Voice Phone +46-18-10 22 80 (Swedish and English spoken) Fax +46-8-729 69 05 (Email *much* preferred) E-Mail: mysql-licensing@tcx.se What Copyright does *MySQL* use? ================================ There are (at least) four different copyright's on the *MySQL* distribution. 1. The *MySQL* specific source needed to make the `mysqlclient' library and programs in the `client' directory is in the public domain. Each file which is in the public domain has a header which clearly states so. This is everything in the `client' directory and some parts of mysys, mystring and dbug libraries. 2. Some small parts of the source (GNU `getopt') are covered by the "GNU LIBRARY LIBRARY GENERAL PUBLIC LICENSE". See the `mysys/COPYING.LIB' file. 3. Some small parts of the source (GNU `readline') are covered by the "GNU GENERAL PUBLIC LICENSE". See the `readline/COPYING' file. 4. Some parts of the source (the `regexp' library) are covered by a Berkeley style copyright. 5. The other source needed for the *MySQL* server is AGPL. See the file PUBLIC for more info. Our philosophy behind this is: - The SQL client library should be totally free so it can be included in commercial products without limitations. - People who want free access to the software we have put a lot of work into can have it so long they do not try to make money directly by distributing it for profit. - People who want the right to keep their own software proprietary, but also want the value from our work, can pay for the privilege. - That means that normal in-house use is FREE. But if you use it for something important to you, you may want to support further development of *MySQL* by purchasing a support license. When may I distribute *MySQL* commercially without a fee? ========================================================= This is a clarification of the information in the '*MySQL* FREE PUBLIC LICENSE'. *Note Public::. *MySQL* may be *used* freely, including by commercial entities for evaluation or unsupported internal use. However, *distribution* for commercial purposes of *MySQL*, or anything containing or derived from *MySQL* in whole or in part, requires a written commercial license from TcX AB, the sole entity authorised to grant such licenses. You may not include *MySQL* "free" in a package containing anything for which a charge is being made except as noted below. The intent of the exception provided in the second clause is to allow commercial organisations operating an FTP server or a bulletin board to distribute *MySQL* freely from it, provided that: 1. The organisation complies with the other provisions of the FPL, which include among other things a requirement to distribute the full source code of *MySQL* and of any derived work, and to distribute the FPL itself along with *MySQL*; 2. The only charge for downloading *MySQL* is a charge based on the distribution service and not one based on the content of the information being retrieved (i.e., the charge would be the same for retrieving a random collection of bits of the same size); 3. The server or BBS is accessible to the general public, i.e., the phone number or IP address is not kept secret, and anyone may obtain access to the information (possibly by paying a subscription or access fee that is not dependent on or related to purchasing anything else). If you want to distribute software in a commercial context that incorporates *MySQL* and you do *not* want to meet these conditions, you should contact TcX AB to find out about commercial licensing. Commercial licenses involve a payment, and include support and other benefits. These are the only ways you legally can distribute *MySQL* or anything containing *MySQL*: either by distributing *MySQL* under the requirements of the FPL, or by getting a commercial license from TcX AB. I want to sell a product that can be configured to use *MySQL*. =============================================================== I want to sell a product that can be configured to use *MySQL* although my customer is responsible for obtaining/installing *MySQL* (or some other supported alternative). Does one of us owe you money if my customer chooses to use *MySQL*? If your product REQUIRES *MySQL* to work, you would have to buy a license. If *MySQL* just added some new features it should fall inside normal use. For example, if using *MySQL* added logging to a database instead of a text file it would not require a license. This would, of course, mean that the user has to fetch and install *MySQL* by himself. If the program is (almost) useless without *MySQL* you would have to get a *MySQL* license to sell your product. I am running a commercial web server using *MySQL*. =================================================== Do I have to get a license for my copy? No, you are not selling *MySQL* itself. But in this case we would like you to purchase *MySQL* support. That is either your support of *MySQL* or our support of you (the later is more expensive since our time is limited). Do I need a license to sell commercial perl/tcl/PHP/Web+ etc applications? ========================================================================== Is your script designed for *MySQL* alone? Does it require *MySQL* to function at all? Or is it designed for `a database' and can run under *MySQL*, PostgreSQL, or something else? If you've designed it strictly around *MySQL* then you've really made a commercial product that requires the engine, so you need to buy a license. If, however, you can support any database with a base level of functionality (and you don't rely on anything that only *MySQL* supports) you probably DO NOT have to pay. It also depends on what you're doing for the client. Are you tying into a database you expect to already exist by the time your software is purchased? Then you again probably don't have to pay. Or do you plan to distribute *MySQL* or give them detailed instructions on installing it with your software? Then you probably do. One thing I'd like to suggest, folks. Look, development won't last forever if nobody pays. I agree that buying a copy for every software user is prohibitive compared to other products available but would it not be courtesy for commercial developers to register their OWN copy that they develop with? Possible future changes in the licensing. ========================================= We may choose to distribute older versions of *MySQL* with the GPL in the future. However these versions will be identified as *GNU MySQL*. Also all copyright notices in the relevant files will be changed to the GPL. Compiling and installing *MySQL* ******************************** How do I get *MySQL*? ===================== You can always check *MySQL*'s home page (http://www.tcx.se/) to read the latest news. But since the Internet connection at TcX is not very fast we would *prefer* if you do the actual downloading from one of the mirrors below. Europe: * Austria WWW [Univ. of Technology/Vienna] (http://gd.tuwien.ac.at/db/mysql/) * Bulgaria FTP [Naturella] (ftp://ftp.ntrl.net/pub/mirror/mysql) * Czech Republic WWW [CESNET] (http://mirror.opf.slu.cz/mysql/) * Denmark WWW [Ake] (http://mysql.ake.dk) * Denmark WWW [SunSITE] (http://SunSITE.auc.dk/mysql/) * Denmark FTP [SunSITE] (ftp://SunSITE.auc.dk/pub/databases/mysql/) * Estonia WWW [Tradenet] (http://mysql.tradenet.ee) * France WWW [minet] (http://www.minet.net/devel/mysql/) * Germany WWW [Wolfenbuettel] (http://www.fh-wolfenbuettel.de/ftp/pub/database/mysql/) * Germany WWW [Staufen] (http://mysql.staufen.de/) * Hungary WWW [Xenia] (http://xenia.sote.hu/ftp/mirrors/www.tcx.se-mysql/) * Israel WWW [Netvision] (http://mysql.netvision.net.il/) * Israel FTP [Netvision] (ftp://mysql.netvision.net.il/mirrors/mysql/) * Italy WWW [Matrice] (http://www.matrice.it/risorse/mysql/) * Poland WWW [Sunsite] (http://sunsite.icm.edu.pl/mysql/) * Poland FTP [Sunsite] (ftp://sunsite.icm.edu.pl/pub/unix/mysql/) * Portugal WWW [Telenet] (http://mysql.telenet.pt) * Russia FTP [Cityline] (ftp://ftp-mysql.cityline.ru/pub/MySQL) * Romania WWW [Timisoara] (http://www.dnttm.ro/mysql) * Romania FTP [Timisoara] (ftp://ftp.dnttm.ro/pub/mysql) * Romania WWW [Bucharest] (http://www.lbi.ro/MySQL) * Romania FTP [Bucharest] (ftp://ftp.lbi.ro/mirrors/ftp.tcx.se) * Sweden WWW [Sunet] (http://ftp.sunet.se/pub/unix/databases/relational/mysql/) * Sweden FTP [Sunet] (ftp://ftp.sunet.se/pub/unix/databases/relational/mysql/) * UK WWW [Omnipotent/UK] (http://mysql.omnipotent.net/) * UK FTP [Omnipotent/UK] (ftp://mysql.omnipotent.net/) * UK WWW [PLiG/UK] (http://ftp.plig.org/pub/mysql/) * UK FTP [PLiG/UK] (ftp://ftp.plig.org/pub/mysql/) North America: * Canada WWW [Polaris Computing] (http://mysql.polaris.ca/) * Canada WWW [Tryc] (http://web.tryc.on.ca/mysql/) * Canada WWW [Cyberus] (http://mysql.cyberus.ca/) * Canada FTP [Cyberus] (ftp://mysql.cyberus.ca/) * USA WWW [Hurricane Electric/San Jose] (http://mysql.he.net) * USA WWW [Buoy/New York] (http://www.buoy.com/mysql/) * USA WWW [Hypernet Communications/Dallas] (http://epsilon.hpnc.com/mysql) * USA WWW [Hurricane Electric/California] (http://mysql.he.net) * USA FTP [Netcasting/West Coast] (ftp://ftp.netcasting.net/pub/mysql/) * USA WWW [Savages/Oregon] (http://mysql.savages.com) * USA WWW [Circle Net/North Carolina] (http://www.mysql.net) * USA WWW [Gina net/Florida] (http://www.gina.net/mysql/) * USA FTP [DIGEX] (ftp://ftp.digex.net/pub/database/mysql/index.html) Asia: * Korea WWW [KREONet] (http://linux.kreonet.re.kr/mysql/) * Japan WWW [HappySize] (http://www.happysize.co.jp/mysql/) * Japan FTP [HappySize] (ftp://ftp.happysize.co.jp/pub/mysql/) * Singapore WWW [Com5 Productions] (http://mysql.com5.net) * Singapore FTP [Com5 Productions] (ftp://ftp.com5.net/pub/mysql) * Taiwan WWW [NCTU] (http://www.iem.nctu.edu.tw/data/mysql) Australia: * Australia WWW [Blue Planet/Melbourne] (http://mysql.bluep.com/) * Australia FTP [Blue Planet/Melbourne] (ftp://mysql.bluep.com/mirror1/mysql/) * Australia FTP [Sage] (ftp://ftp.sage-au.org.au/pub/database/mysql) Which *MySQL* version should I use? =================================== The first decision is if you want to use the latest development release or the last stable release. Normally if you are starting with development we recommend going with the development release. This is because there are usually no really bad bugs in the development release and you can easily test it on your machine with the crash-me and benchmark tests. *Note Benchmarks::. The second decision is if you want a source or a binary release. If you want to run *MySQL* on a platform that has a current binary release, use that. A binary version of *MySQL* is easier to install. If you want to read (and/or modify) the C and C++ code that makes up *MySQL* you should always get a source distribution. The code is always the ultimate manual. The source distribution also contains more tests and examples than the binary distribution. To clarify our naming schema: All *MySQL* versions are run through our standard test and the benchmarks to ensure that they are relatively safe to use. The standard tests are also extended the whole time to test for all previously found bugs, so it gets better the whole time. The *MySQL* release numbers consist of 3 numbers and a suffix. So a release name like `mysql-3.21.17-beta' means. The first number. In this case 3 This describes the file format. So all version 3 releases has the same file format. And when a version 4 appears every table has to be converted to the new format (Nice tools for this will of course be included). The second number. In this case 21 This is the release level. Normally there are two to choose from. One is the release/stable branch and the other is the development branch. Normally both are stable but the development version may have quirks, missing documentation and may fail to compile on some systems. The third number. In this case 17 This is the version number. This is incremented for each release. Usually you want the latest version for the release you have choosen. The suffix. In this case beta * Alpha means that some new large code section exists which hasn't been tested to 100%. Known bugs should be documented in the News section (usually there are none). There are also new commands and extensions in most alpha releases. * Beta means that all new code has been tested. No major new things are added. There should be no known bugs. * Gamma is a beta that has been around a while and seems to work fine. This is what many other companies call a release. * Release (no extension) means that the version has been run for a while at many different sites without any bug reports (Except platform-specific bugs). Note that all releases have at least been tested with: A internal testsuite This is part of a production system for a customer. It has many tables and with many megabytes of data and lots of tables. The *MySQL* benchmark suite This runs a range of common queries. It is also a test to see whether the latest batch of optimisations actually made the code faster. *Note Benchmarks::. The crash-me test This tries to find out what the database supports and which limitations it has. *Note Benchmarks::. Another test is our internal production. We usually use the latest version for this (at least on one machine) and we have more than 100 gigabytes of data to work with. How/when will you release updates? ================================== We are using the following policy when updating *MySQL*: Each minor update will increment the last number in the version string. When there are major new features or minor incompatibilities with previous versions, the second number in the version string will be incremented. When the file format changes the first number will be increased. * Stable tested releases are meant to appear about 1-2 times a year. But if small bugs are found, a release with only bug-fixes will be released. * Working releases are meant to appear about every 1-8 weeks. * Binary releases for some platforms will be made for major releases by us. Other people may make binary releases for other systems but probably less frequently. * We usually make patches available as soon as we have located and fixed small bugs. * For non-critical but annoying bugs, we will make patches available if they are sent to us. Otherwise we will combine many of them into a bigger patch. Which operating systems does *MySQL* support? ============================================= We use GNU autoconf so it is possible to port *MySQL* to all modern systems with working Posix threads and a C++ compiler. The client code requires C++ but not threads. We use/develop the software ourselves primarily on Sun Solaris (versions 2.5 & 2.6) and some on RedHat Linux 5.0. The following OS/thread packages have been reported to compile *MySQL* successfully. Note that for many OSes the native thread support only works in the latest versions. * Solaris 2.5 & 2.6 with native threads. * SunOS 4.x with the included MIT threads package. * BSDI 2.x with the included MIT threads package. * BSDI 3.0 and 3.1 native threads. * SGI IRIX 6.x with native threads. * AIX 4.x whith native threads. * DEC UNIX 4.x with native threads. * Linux 2.0+ with LinuxThreads 0.5, 0.6 and 0.7. * FreeBSD 2.x with the included MIT threads package. * FreeBSD 3.x with native threads. * SCO OpenServer with a recent port of the FSU-threads package. * NetBSD 1.3 Intel and NetBSD 1.3 Alpha. * Openbsd 2.1 * HPUX 10.20 with the included MIT threads package. * Win95 and NT. This version is currently only available for users with a *MySQL* license or *MySQL* email support. Compiling *MySQL* from source code. =================================== What you need: 1. GNU `gzip' to uncompress the distribution. 2. A reasonable `tar' to unpack the distribution. GNU `tar' is known to work. 3. A working ANSI `C++' compiler. gcc >= 2.7, SGI C++, SunPro C++ are some of the compilers that are known to work. `libg++' is not needed when using `gcc'. 4. A good `make' program. If you have problems we recommend trying GNU `make'. Quick installation overview. ---------------------------- Unpack tar archive in a directory. The tar file should be named like mysql-VERSION.tar.gz (VERSION is a number like 3.21.30). A directory named mysql-VERSION should be created. `zcat mysql-VERSION.tar.gz | tar xvf -' Unpack the distribution into the current directory. `cd mysql-VERSION' Change directory. `./configure' Configure the release. Here you might want to add some options. For a list of configure options use `./configure --help'. `make' Compile everything. `make install' Install everything. `./scripts/mysql_install_db' Set up the *MySQL* privilige tables. This only needs to be done the first time you install *MySQL*. You may want to edit this script before running it to get right initial permissions for users to connect to the database. `'installation_directory'/bin/mysqladmin version' Check to see if the server is running. Unless you added some options to `./configure' 'installation_directory' is `/usr/local'. Here is an example of the output you should get (You will not get this exactly!): mysqladmin Ver 6.3 Distrib 3.21.17, for pc-linux-gnu on i686 TCX Datakonsult AB, by Monty Server version 3.21.17-alpha Protocol version 10 Connection Localhost via UNIX socket TCP port 3306 UNIX socket /tmp/mysql.sock Uptime: 16 sec Running threads: 1 Questions: 20 Reloads: 2 Open tables: 3 Remember that if you reconfigure *MySQL* you have to do `rm config.cache' or `make distclean' before doing a new configure! Usual configure switches: * To compile only the client use `--without-server'. If you only want to have the client library and don't have a C++ compiler, you can remove the code in configure (in the source distribution) that tests for the C++ compiler and then compile with -without-server. Ignore in this case any warnings about `mysql.cc' (The only *MySQL* client that needs C++). * If you don't want to have your data under `/usr/local/var' use something like: `--prefix=/usr/local' or `--prefix=/usr/local --localstatedir=/usr/local/data/mysql' * If you don't want to have your sockets in the default place (default is `/tmp' or `/var/run') use `--with-unix-socket-path=absolute_file_name' * If you get errors compiling sql_yacc.yy errors like: `Internal compiler error: program cc1plus got fatal signal 11' or `Out of virtual memory' you can try the configure switch: `--with-low-memory'. This adds `-fno-inline' to the compile line if you are using gcc and -O0 if you are using something else. The problem is that gcc requires about 180M to compile sql_yacc.cc with inline functions. * Changing the default character set. By default *MySQL* will use the ISO8859-1 (Latin1) character set. You may change this at compile time by the configure switch `--with-charset=charset'. Where [charset] may be one of: `big5', `czech', `dec8', `dos', `german1', `hp8', `koi8_ru', `latin1', `latin2', `swe7', `usa7', `ujis', or `sjis'. If you want to add another character set to *MySQL* you must: * Choose a name. CHARSET_NAME * Create the file `mysql_source_directory/strings/ctype-$CHARSET_NAME.c'. * Look at one of the existing ctype files to see what needs to be defined. Note that the arrays in this file must have names like ctype_$CHARSET_NAME, to_lower_$CHARSET_NAME and so on. * Add to include/m_ctype.h.in a unique number for the char set. * Add charset name to `CHARSETS_AVAILABLE' list in `configure'.in * Recompile and test * If you are making a multiple-character char set, you can use the _MB macros. In `strings/m_ctype.h.in' add: #define MY_CHARSET_ X #if MY_CHARSET_CURRENT == MY_CHARSET_ #define USE_MB #define USE_MB_IDENT #define ismbchar(p, end) (...) #define ismbhead(c) (...) #define mbcharlen(c) (...) #define MBMAXLEN N #endif MY_CHARSET_ unique value. USE_MB This charset have mb-char. USE_MB_IDENT: Use mb-char as identifier. (optional) ismbchar(p, e) return 0 if not mb-char, or size of char if mb-char. Check from (char*)p to (char*)e-1. ismbhead(c) Is c first char of mb or not? mbcharlen(c) Size of char if c is first char of mb. MBMAXLEN Maximum size of one character. If you want to convert characters between the server and the client, you should take a look at the `SET OPTION CHARACTER SET'. *Note Set option:: *Warning:* If you change character sets after having created a table you will have to run `isamchk -r -q' on every table. Otherwise things will be sorted incorecctly in some cases (but not all!). * For computer/OS specific switches, see the menu later in this chapter. GNU `make' is always recommended and is sometimes required. About creating the grants database `mysql_install_db': The default priviliges is that anybody may create/use the databases named `test' or starting with `test_'. `root' can do anyting. *Note Privileges::. To change the defaults edit the script before running it. If this is the first time you install *MySQL* you must run this command. If you don't do it you will get the error: `Can't find file: './mysql/host.frm''. This script also starts the mysqld daemon the first time. If you want to change things in the grant tables after installing you should use `mysql -u root mysql' to connect to the grant tables as the 'root' user. Normal start of the *MySQL* server daemon (not needed the first time): `'installation_directory'/bin/safe_mysqld --log' Applying a patch ---------------- Some times patches appear on the mailing list. To apply them, do something like this: cd 'old-mysql-source-distribution-path' gunzip < patch-file-name.gz | patch -p1 rm config.cache make clean And then follow the instructions for a normal source install from the `./configure' step. And then restart your *MySQL* server. Problems compiling ? ==================== If your compile fails with something like: configure: error: installation or configuration problem: C++ compiler cannot create executables. Try setting the environment variable `CXX' to `"gcc -O3"' (If you are using `gcc'). For example `CXX="gcc -O3" ./configure'. If you use this you don't nead to have libg++ installed! If you have any problems with using g++, or libg++ or libstdc++, you can probably always solve these by configuring as above! You can also install libg++. By default `configure' picks `c++' as a compiler name and GNU `c++' links with `-lg++'. 1. making all in mit-pthreads make: Fatal error in reader: Makefile, line 18: Badly formed macro assignment This means you have to upgrade your make to GNU `make'. 2. If you want to add flags to your C or C++ compiler, add the flags to the CC and CXX environment variables. For example: CC="gcc -O4" CXX="gcc -O4" export CC CXX 3. If your `make' stops with `Can't find Makefile.PL' when you should try using GNU `make'. Solaris and FreeBSD are known to have troublesome `make' programs. 4. If you get error messages from make or error message of type: `pthread.h: No such file or directory' This means you have to upgrade your `make' to GNU `make' (GNU `make' version 3.75 is known to work). 5. If you get a error message like: `client/libmysql.c:273: parse error before `__attribute__'' This means you need to upgrade your gcc compiler (2.7.2 is known to work). 6. If configure fails, and you are going to mail , please include any lines from config.log that you think can help solve the problem. Also include a couple of lines of the last output from configure if configure aborts. Post the bug using the 'mysqlbug' script. *PLEASE ALWAYS USE `mysqlbug'* when posting questions to . *Note Bug reports::. Even if the problem isn't a bug, mysqlbug gathers some system information that will help others solve your problem! 7. If you need to debug mysqld or a *MySQL* client, run configure with: `configure --with-debug=yes' and link your clients with the new client library. Before running a client you should do: MYSQL_DEBUG=d:t:O,/tmp/client.trace export MYSQL_DEBUG You will now get a trace file in `/tmp/client.trace'. 8. If you get three errors when compiling mysqld like: cxx: Error: mysqld.cc, line 645: In this statement, the referenced type of the pointer value "&length" is "unsigned long", which is not compatible with "int". new_sock = accept(sock, (struct sockaddr *)&cAddr, &length); Then configure didn't detect the type of the last argument to `accept()', `getsockname()' and `getpeername()'. Search after the line: /* Define as the base type of the last arg to accept */ #define SOCKET_SIZE_TYPE ### and change ### to size_t or int depending on your operating system. 9. If you have problem with your own client code, test first with `mysql --debug=d:t:o,/tmp/client.trace' before mailing a bug report. *Note Bug reports::. General compilation notes ========================= All *MySQL* programs compile clean (no warnings) for us (on Solaris using gcc). But warning may appear because of different system include files. Se below for warnings that may occur when using mit-pthreads. You probably have to use bison to compile sql_yacc.yy. If you get an error like: "sql_yacc.yy", line xxx fatal: default action causes potential... you have to install bison (the GNU yacc). If you want to have static linked code, use (with gcc): `LDFLAGS="-static" ./configure ...' MIT-pthreads notes. (FreeBSD) ============================= You can on most systems force the usage of mit-pthreads with the configure switch `--with-mit-threads'. Building in a non source directory is not supported when using MIT-threads. This is because we want to keep our changes to this code minimal. MIT-pthreads doesn't support the `AF_UNIX' protocol so we must use the TCP/IP protocol for all connections (which is a little slower). If you can't connect to a table, try using the host (`-h' or `--host') switch to `mysql'. This must be done if you have compiled the client code `--without-server' because the default connection is to use Unix sockets. *MySQL* compiled with MIT threads has system locking disabled by default for performance reasons. One can start the server with system locking with the `--use-locking' switch. Sometimes (at least on Solaris) the pthread `bind()' command fails to bind to a socket without any error message. The result of this is that all connections to server fails. > mysqladmin ver mysqladmin: connect to server at '' failed; error: 'Can't connect to mysql server on localhost (146)' The solution to this is to kill the `mysqld' daemon and restart it. This has only happened to us when we have forced the daemon down and done a restart immediately. `sleep()' isn't interruptible with `SIGINT' (break) with MIT-threads. This is only notable in `mysqladmin --sleep'. One must wait for the end of the `sleep()' before the interrupt is served and the process stops. We haven't got readline to work with MIT threads. (This isn't needed, but may be interesting for someone) When linking (at least on Solaris) you will receive warning messages like: ld: warning: symbol `_iob' has differing sizes: (file /my/local/pthreads/lib/libpthread.a(findfp.o) value=0x4; file /usr/lib/libc.so value=0x140); /my/local/pthreads/lib/libpthread.a(findfp.o) definition taken ld: warning: symbol `__iob' has differing sizes: (file /my/local/pthreads/lib/libpthread.a(findfp.o) value=0x4; file /usr/lib/libc.so value=0x140); /my/local/pthreads/lib/libpthread.a(findfp.o) definition taken Some other warnings which also can be ignored: implicit declaration of function `int strtoll(...)' implicit declaration of function `int strtoul(...)' Perl installation comments. =========================== The included perl client code requires perl5.004 or later. If you got a the following error (from mysqlperl or DBD-mysql): /usr/bin/perl: can't resolve symbol '__moddi3' /usr/bin/perl: can't resolve symbol '__divdi3' You are probably using gcc (or using an old binary compiled with gcc). Add `-L/usr/lib/gcc-lib/... -lgcc' to the link command where `-L/...' is the path to the directory where `libgcc.a' exists. Special things to consider for some machine/OS combinations. ============================================================ Solaris notes. -------------- Sun native threads only work on Solaris 2.5 and higher. For 2.4 and earlier versions, you can use MIT-pthreads. *Note MIT-pthreads::. If there are too many processes that try to connect very rapidly to the `mysqld' one will get `Error in accept : Protocol error' in the mysql log. If you have the Sun Workshop 4.2 compiler you can configure with: `CC="cc -Xa -fast -xstrconst" CXX="CC -xsb -noex -fast" ./configure' You may also have to change the row in configure: `#if !defined(__STDC__) || __STDC__ != 1' to `#if !defined(__STDC__)' because if you turn on `__STDC__' with the `-Xc' switch, the Sun compiler can't compile with the Solaris `pthread.h' header files anymore. This is a Sun bug (Broken compiler or broken include file). If the compiled `mysqld' gives a error like: `libc internal error: _rmutex_unlock: rmutex not held.' you probably are using the Sun pro compiler on Solaris 2.6. Either ask sun for a working compiler or upgrade to gcc (gcc also produces about 10% faster C++ code). The tar in Solaris can't handle long file names; You may get the following error (or something similar) when unpacking the *MySQL* distribution: x mysql-3.21.21a-beta-sun-solaris2.6-sparc/perl/Mysql-modules/blib/lib/auto/Msql-Mysql-modules, 0 bytes, 0 tape blocks tar: directory checksum error You have to use gnu tar to unpack the distribution. You can find copy of precompiled gnu tar (gtar) for Solaris at `http://www.mysql.com/Downloads/' SunOS 4 notes. -------------- On SunOS 4, MIT-pthreads is needed. You must have GNU `make' to compile (because of MIT-pthreads). In readline you may get warnings about duplicate defines. These may be ignored. When compiling mysqld there will be some warnings about `implicit declaration of function'. These may be ignored. Linux notes for all versions ---------------------------- On Linux you should use the `--skip-locking' flag to `mysqld' (it is added automatically by `safe_mysqld'). This is because a bug in Linux file locking calls. This bug is known to exist as recently as Linux version 2.0.32. When using LinuxThreads you will see a minimum of three processes running. These are in fact threads. There will be one thread for the Linux Threads manager, one thread to handle connections, and one thread to handle alarms and signals. if you are using RedHat you might get errors like: /usr/bin/perl is needed... /usr/sh is needed... /usr/sh is needed... If so upgrade rpm itself to rpm-2.4.11-1.i386.rpm & rpm-devel-2.4.11-1.i386.rpm (or later versions). You can get the 4.2 updates from `ftp://ftp.redhat.com/updates/4.2/i386'. Or `http://www.sunsite.unc.edu/pub/Linux/distributions/redhat/code/rpm/' for other distributions. Linux-x86 notes. ................ LinuxThreads should be installed before configuring *MySQL*! *MySQL* requires libc version 5.4.12 or newer. glibc version 2.0.6 and later should also work. There has been some problems with the glibc rpms from RedHat so if you have problems, check if there are any updates! On some older Linux distributions `configure' may give a error about: `Syntax error in sched.h. Change _P to __P in the /usr/include/sched.h file.\ See the Installation chapter in the Reference Manual'. Just do what the error says and add a extra underscore to the `_P' macro that only has one underscore. Then try again. You may get some warnings when compiling: (these can be ignored) mysqld.cc -o objs-thread/mysqld.o mysqld.cc: In function `void init_signals()': mysqld.cc:315: warning: assignment of negative value `-1' to `long unsigned int' mysqld.cc: In function `void * signal_hand(void *)': mysqld.cc:346: warning: assignment of negative value `-1' to `long unsigned int' If you want in Debian GNU/Linux to get *MySQL* to auto start when system boots, do the following: > cp scripts/mysql.server /etc/init.d/mysql.server > /usr/sbin/update-rc.d mysql.server defaults 99 If mysqld always core dumps when starting, the problem may be that you have an old `/lib/libc.a'. Try renaming this, remove sql/mysqld and do a new make install and try again. This problem has been reported on some Slackware installations. RedHat 5.0 .......... If you install all the official redhat patches (including glibc-2.0.6-9 and glibc-devel-2.0.6-9) it should work out of the box (se above for how to configure). The updates are needed since there is a bug in glibc 2.0.5 in how pthread_key_create variables are freed. With glibc 2.0.5 you must use the static-linked *MySQL* binary distribution. If you want to compile from source you must install the corrected version of Linuxthreads from `http://www.tcx.se/Downloads/Linux' or upgrade your glibc. If you have a wrong glibc or linuxthread version the symptom is that mysqld crashes after each connections. For example `mysqladmin version' will crash mysqld when it finishes! Another symptom of wrong libraries is that mysqld crashes at once when it starts. One some Linux systems this can be fixed by configuring with `LDFLAGS=-static ./configure'. On some RedHat 5.0 system it will only work WITHOUT `LDFLAGS=-static'. This is known to happen even with new versions as glibc 2.0.7-4 ! For the source distribution of glibc 2.0.6 you can find a patch at `http://www.tcx.se/Download/Linux/glibc-2.0.6-total-patch.tgz' that is easy to apply and is tested with `MySQL'! If you experience crashes like these when you build *MySQL*, you can always download the newest binary version of MySQL. This is compiled staticly to avoid library conflicts and should work on all Linux systems! Linux-Sparc notes. .................. In some implementations `readdir_r' is broken. This will be noticed when `SHOW DATABASES' always returns an empty set. This can be fixed by removing `HAVE_READDIR_R' from `config.h'. Some problems will require patching your Linux installation. The patch can be found at `http://www.tcx.se/patches/Linux-sparc-2.0.30.diff'. This patch is against the Linux distribution `sparclinux-2.0.30.tar.gz', that is available at vger.rutgers.edu. This is a version Lf linux which was never merged with the official 2.0.30. You must also install linuxthreads 0.6 or newer. Thanks to jacques@solucorp.qc.ca for the above information. Linux-Alpha notes. .................. The first problem is linuxthreads. You must patch linuxthreads for alpha because the RedHat distribution uses an old (broken) linuxthreads version. 1. Obtain the glibc2.5c source from any GNU ftp site. 2. Get the file `ftp://www.tcx.se/pub/mysql/linux/patched-glibc-linuxthreads-0.6.tgz'. This includes a fixed .c file. Copy this to the glibc `./linuxthreads' directory. 3. Configure and compile glibc (You have to read the manual how to do this together with linuxthreads). Don't install this! 4. Rename your old version of /usr/lib/libpthread.a to /usr/lib/libpthread.a-old 5. Copy the file glibc.../linuxthreads/libpthread.a to /usr/lib. 6. Configure *MySQL* with (everything on one row): CC=gcc CCFLAGS="-Dalpha_linux_port" CXX=gcc CXXFLAGS="-O3 -Dalpha_linux_port" ./configure --prefix=/usr/local/mysql 7. Try to compile mysys/thr_lock and mysys/thr_alarm. Test that these work! 8. Recompile mysqld. Note that Alpha-Linux is still an alpha platform for MySQL. With RedHat 5.0 and the patched linuxthreads you have a very good chance of it working. Alpha-DEC-Unix notes. --------------------- When compiling threaded programs under Digital UNIX using CC / CXX the documentation recommends the switch to cc and cxx and the libraries `-lmach -lexc' (in addition to `-lpthread'). So you have to configure with something like this: `CC="cc -pthread" CXX="cxx -pthread -O" ./configure -with-named-thread-libs="-lpthread -lmach -lexc -lc"' When compiling mysqld you will may this warning for mysqld for a couple of lines: mysqld.cc: In function void handle_connections()': mysqld.cc:626: passing long unsigned int *' as argument 3 of accept(int,sockad ddr *, int *)' You can safely ignore these. This is because configure can't detect warnings, only errors. You may get problems with the server exiting directly. If so, try starting it with `nohup safe_mysqld [options]' `nohup' is a command that ignores any `SIGHUP' sent from the terminal. Alpha-DEC-OSF1 notes. --------------------- If you have problems compiling and have Dec CC and gcc installed you can try the following compile line (with sh or bash): CC=cc CFLAGS=-O CXX=gcc CXXFLAGS=-O3 ./configure -prefix=/usr/local/mysql On OSF1 V4.0D and compiler "DEC C V5.6-071 on Digital UNIX V4.0 (Rev. 878)" the compiler had some strange behaviour (One gets undefined 'asm' symbols). /bin/ld appears also to be broken (one gets _exit undefined when linking mysqld). On this we have managed to compile MySQL with the following configure line, after replacing /bin/ld from OSF 4.0C: CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure -prefix=/usr/local/mysql In some versions of OSF1, the `alloca()' functions is broken. Fix this by removing `'HAVE_ALLOCA'' from config.h. The `alloca()' function can also have a wrong prototype in `/usr/include/alloca.h'. This warning can be ignored. Configure will automaticly use the following thread libraries: `-with-named-thread-libs="-lpthread -lmach -lexc -lc"' When using gcc you can also try to use: CFLAGS=-D_PTHREAD_USE_D4 CXX=gcc CXXFLAGS=-O3 ./configure .... SGI-IRIX notes. --------------- You may have to undefine some things in `config.h' (generated by `./configure'). In some Irix implementations the `alloca()' function is broken. If the mysqld server dies on some selects, remove `HAVE_ALLOC' & `HAVE_ALLOCA_H' from `config.h'. If mysqladmin create doesn't work, remove `HAVE_READDIR_R' from config.h. Also you may have to remove `HAVE_TERM_H'. Irix 6.2 doesn't support POSIX threads out of of the box. You have install these patches, available from SGI if you have support: 1403, 1404, 1644, 1717, 1918, 2000, 2044 If you get the something like the following error when compiling mysql.cc: "/usr/include/curses.h", line 82: error(1084): invalid combination of type Type the following in the mysql installation directory: > extra/replace bool curses_bool < /usr/include/curses.h > include/curses.h > make There have also been reports about scheduling problems. This is because if only one thread is running, things go slow. Avoid this by starting another client. This may lead to a 2-10 fold increase in execution speed thereafter for the other thread. This is a poorly-understood problem with IRIS threads, so you may have to improvise to find solutions until this can be fixed. If you are compiling with gcc, you can use the following configure line: CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure -prefix=/usr/local/mysql -with-thread-safe-client FreeBSD notes. -------------- If you get a error on 'make install' that it can't find /usr/include/pthreads, configure didn't detect that one neads mit-threads on FreeBSD. This is fixed by doing: rm config.cache ./configure --with-mit-threads If you get link errors when compiling mysqlperl (Type `ient.a(my_getwd.o): RRS text relocation at 0x9a9f for "__db_pargs_"') You must recompile the Perl code with `-DPIC -fpic'. Do the following: 1. First install everything. 2. Change in `client/Makefile' the line: `CFLAGS = -g -O2' to `CFLAGS = -O2 -DPIC -fpic' 3. `cd client' 4. `rm *.o' 5. `make libmysqlclient.a' 6. `cd ../perl' 7. `make' This shall hopefully be handled automatically in the future. The FreeBSD `make' behaviour is slightly different from GNU `make'. If you have a problem that `perl/Makefile' doesn't get generated, you should install GNU `make'. If mysql or mysqladmin takes a long time to respond, a user said the following: Are you running the ppp user process? On ine FreeBSD box (2.2.5) MySQL clients takes a couple of seconds to connect to mysqld if the ppp process is running. FreeBSD is also known to have a very low default file handle limit. *Note Not enough file handles:: If you have a problem that select NOW() returns GMT and not your local time, you have to set the `TZ' environment variable to your current timezone. FreeBSD-3.0 notes. .................. You have to configure with: `--with-named-thread-libs=-lc_r' The pthreads library for FreeBSD doesn't contain the `sigwait' function and there is some bugs in it. To fix this, get the `FreeBSD-3.0-libc_r-1.0.diff' file and apply this in the `/usr/src/lib/libc_r/uthread' directory. Follow after this the instructions that can be found with `man pthread' about how to recompile the `libc_r' library. You can test if you have a 'modern' `libpthread.a' with: > nm /usr/lib/libc_r.a | grep sigwait. If the above doesn't find `sigwait' you have to use the above patch and recompile `libc_r'. BSD/OS 2.# notes ---------------- From Jan Legenhausen . I finally got mysqlperl working on BSDI2.1. What i did was almost nothing: 1. cd client 2. Leave the Makefile as it is! (i use `GCC="shlicc2"' per default; perl5 automagically uses shlicc2 - you should use _one_ version (either `gcc' or `shlicc2') for both `Mysql.c' and `libmysqlclient.a'!) 3. `rm *.o' 4. `gmake libmysqlclient.a' 5. `cd ../perl/mysqlperl' 6. `make clean' 7. add `$sysliblist=" -L$tmp -lgcc -lcompat";' to Makefile.PL line 45 (just to be sure - i didn't check if one could leave out this one) 8. `perl Makefile.PL' 9. remove all old `libmysqlclient.a''s in `/usr/lib' and `/usr/contrib/lib' 10. `make install' If you get the following error when compiling *MySQL*: item_func.h: In method `Item_func_ge::Item_func_ge(const Item_func_ge &)': item_func.h:28: virtual memory exhausted make[2]: *** [item_func.o] Error 1 Then your ulimit for virtual memory is too low. Try using: `ulimit -v 80000' and do `make' again. If you are using gcc you can also add the flag '-fno-inline' to the compile line when compiling sql_yacc.cc. If you have a problem that select NOW() returns GMT and not your local time, you have to set the `TZ' environment variable to your current timezone. BSD/OS 3.# notes. ................. 1. Upgrade to BSD/OS 3.1. If that is not possible, install BSDIpatch M300-038. 2. Use the following configuration when installing *MySQL*: env CXX=shlicc++ CC=shlicc2 ./configure --prefix=/usr/local/mysql --localstatedir=/var/mysql --without-perl --with-unix-socket-path=/var/mysql/mysql.sock The following is also known to work: env CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-unix-socket-path=/var/mysql/mysql.sock 3. If you have problems with performance under heavy load, try using the -skip-thread-prior switch to safe_mysqld! This will run all threads with the same priority and on BSDI 3.1 this gives better performance. (At least until BSDI has fixed their thread scheduler). You can change the directory locations if you wish, or just use their defaults by not specifying them. SCO notes. ---------- The current port is only tested on a 'sco3.2v5.0.4' system. 1. For OpenServer 5.0.X You need to use GDS in Skunkware 95 (95q4c). This is necessary because GNU gcc 2.7.2 in Skunkware 97 does not have GNU `as'. 2. You need the port of GCC 2.5.? for this product and the Developement system. They are required on this version of SCO UNIX. You can not just use the GCC Dev system. 3. One should get FSU thread package and install this first. This can be found at: `http://www.cs.wustl.edu/~schmidt/ACE_wrappers/FSU-threads.tar.gz' You can also get a precompiled package from: `ftp://www.tcx.se/pub/mysql/SCO/fsu-threads.tar.gz' 4. FSU pthreads can be compiled with SCO UNIX 4.2 with tcpip. Or OpenServer 3.0 or Open Desktop 3.0 (OS 3.0 ODT 3.0), with the SCO Developement System installed using a good port of GCC 2.5.X ODT or OS 3.0 you will need a good port of GCC 2.5.? There are a lot of problems with out a good port. The port for this product requires the SCO UNIX Developement system. Without it, you are missing the libraries and the linker that is needed. 5. To build FSU pthreads in your system do the following: 1. Run ./configure in threads/src directory and select the SCO OpenServer option. This command copy Makefile.SCO5 to Makefile. 2. Run make. 3. To install in default /usr/include directory, login as root and cd to thread/src directory, run make install. 6. Remember to use GNU `make' when making *MySQL*. 7. If you don't start safe_mysqld as root, you will probably only get the default 110 open files per process. mysqld will write a note about this in the log file. SCO development notes: * *MySQL* should automaticly detect FPU-threads and link mysqld with: `-lgthreads -lsocket -lgthreads' * The SCO development libraries are reentrant in FSU pthreads. SCO claims that its libraries function are reentrant so they must be reentrant with FSU pthreads. FSU pthreads on OpenServer tries to use the SCO scheme to make reentrant library. * FSU threads (at least the version at www.tcx.se) comes linked with GNU malloc. If you get problems with memory usage, check that gmalloc.o is included in libgthreads.a and libgthreads.so * In FSU pthreads, the following system calls are pthread aware: read, write, getmsg, connect, accept, select and wait. IBM-AIX notes. -------------- When using the IBM compiler, something like this is needed: CC="xlc_r -ma -O3 -qstrict" CXX="xlC_r -ma -O3 -qstrict" ./configure Automatic detection of xlC is missing from autoconf. HPUX notes. ----------- There is a couple of 'small' problems when compiling mysql on HPUX. Below we describe some problems and workarounds when using the HPUX compiler and gcc 2.8.0 . gcc 2.8.0 can't compile readline on HPUX (internal compiler error). mit-pthreads can't be compiled with HPUX compiler, because it can't compile .S (assembler) files. We got MySQL to compile on HPUX 10.20 by doing the following: CC=cc CFLAGS="+z +e -Dhp9000s800 -D__hpux__" CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-low-memory cd mit-pthreads rm config.cache CC=gcc CXX=gcc ./configure cd .. make make install scripts/mysql_install_db Win32 notes =========== The *MySQL*-win32 version has by now proven itself to be very stable. The *MySQL*-win32 version has all the features as the corresponding Unix version of *MySQL* with the following exceptions: `ALTER TABLE' One can't do a `ALTER TABLE' on file if it is hold open by another thread or the table cache. On *MySQL*-win32 I have added code to close the file owned by the thread that does `ALTER TABLE' but *MySQL* can't yet close the the file descriptors used by other threads. We have to do a major recode of the file lock system to handle this. For now, when using `ALTER TABLE', one must be sure that no other threads are using the table. One can be sure of this by doing a 'mysqladmin refresh' before doing an `ALTER TABLE'. `Increasing the table cache' Win32 has only a very limited number of open files it can handle at the the same time (about 255). Because of this one shouldn't increase the number of open connections or number of cached tables very much on Win32. `Win95 and threads' Win95 leaks memory for each threads. Because of this one shouldn't run mysqld for an extended time on Win95 if one does many connections as each connection in MySQL creates a new thread! NT doesn't suffer from this bug. Other win32 specific issues are described in the README file that comes with the *MySQL*-win32 distribution. Installation instructions for *MySQL* binary release ==================================================== *Please* always use the mysqlbug script when posting questions to the mailinglist (). Even if the problem isn't a bug, mysqlbug gathers some system information that will help other solve your problem! *Note Bug reports::. 1. Get the distribution. That is a file called something like mysql-version-OS.tgz. For example a file holding a *MySQL* version 3.21.15 for a intel linux machine is called `mysql-3.21.15-alpha-pc-linux-gnu-i586.tgz'. 2. Pick a directory to put *MySQL* in: In the following we will use `/usr/local/mysql' as the installation directory and *MySQL* version VERSION (something like 3.21.15) for SunOS5 (Solaris), for example. 3. All of the following instructions assume you have permission to create files in `/usr/local'. Use the following commands to create the directory and unpack the distribution: > cd /usr/local > zcat //mysql-3.20.0-SunOS5.tgz | tar xvf - > ln -s mysql-VERSION mysql 4. After this you should install the *MySQL* privilege tables. In some binary versions the grant tables may already be created, for others distributions you should edit the `scripts/mysql_install_db' script to have the privileges you want and run it. The default privileges is that anybody may create/use the databases named 'test' or starting with "test_". The *MySQL* user root can do anything. Note that you do not have to run the *MySQL* server as root. Any user is ok as long as it can read and write in the installtion directories/files. If you want to recreate the privilege tables remove all the *.ISM and *.ISD files in the mysql database directory, edit the scripts/mysql_install_db script to have the privileges you want and run it. This creates the privilige tables if they don't exist: > scripts/mysql_install_db *Note mysql_install_db:: If you want to change things in the grant tables after installing you should use `mysql -u root mysql' to connect to the grant tables as the 'root' user. The `mysql_install_db' script also starts the `mysqld' daemon. 5. Normally, start the *MySQL* server daemon (not needed the first time): > bin/safe_mysqld --log & 6. You can test that the daemon is running by doing this: > bin/mysqladmin ver That should print something like this. The exact output depends on you platfrom and use. bin/mysqladmin Ver 6.3 Distrib 3.21.15-alpha, for SOLARIS 2.5 on SPARCstation TCX Datakonsult AB, by Monty Server version 3.21.15-alpha Protocol version 9 Connection Localhost via UNIX socket TCP port 3306 UNIX socket /tmp/mysql.sock Uptime: 2 days 1 hour 42 min 3 sec Running threads: 2 Questions: 450378 Reloads: 17 Open tables: 64 To get perl work do the following: ---------------------------------- cd perl/DBI perl Makefile.PL make make install cd ../Mysql-modules perl Makefile.PL make make install You should use the `safe_mysqld' script to the server. `safe_mysqld' expects one of two conditions to be true: 1. You're executing the script from the base mysql installation directory (for example `/usr/local/mysql') 2. The server should reside in `/my/'. To get it to run correctly, you should cd to `/usr/local/mysql' and then execute `safe_mysqld' or modify the script so that it expects the base mysql directory to be `/usr/local/mysql' rather than the default `/my/'. When you execute this: > bin/mysqld --help You will get the options for mysqld (and safe_mysqld) and the current paths. Normally you only should need to change the `--basedir=path'. You can test the path switches by executing: > bin/mysqld --basedir=/usr/local --help If you would like to use mysqlaccess and have the mysql distribution in some nonstandard place, you must change the path to mysql in mysqlaccess. `bin/mysqlaccess' about line 308: $MYSQL = '/usr/local/bin/mysql --batch --unbuffered'; If you don't change the path, you will get a 'broken pipe' error when using mysqlaccess. If you would like *MySQL* to start when you boot your machine, you can copy `bin/mysql.server' to where your system has it startup files. More information can be bound in the bin/mysql.server script itself. Linux notes. ------------ * MySQL needs at least Linux 2.0. * The binary release is linked with -static, which means that you don't have to worry about which version of your system libraries. You don't have to install LinuxThreads either. A program linked with -static is slightly bigger but also slighty faster (3-5%) than a dynamicly linked program. The only problem is that you can't use UDF (user definable functions) with a -static program. If you are going to write or use UDF functions (this is only something for C or C++ programmers) you have to compile MySQL yourself. * The Linux-intel binary release is compiled with "pgcc -O6 -mpentium -mstack-align-double" for more speed. * The perl distribution needs perl5.004.03 or newer. HP/UX notes. ------------ The binary distribution of *MySQL* for HP/UX is distributed as an HP depot file. This means that you must be running at least HP/UX 10.x to have access to HP's software depot tools. This version of *MySQL* was compiled on an HP 9000/8xx server under HP/UX 10.20, and uses MIT Pthreads. It is known to work well under this configuration. This version does *not* use HP's native thread package. It is highly unlikely that *MySQL* will use HP native threads on anything but HP/UX 10.30 or later. Other configurations that may work: 9000/7xx - HP/UX 10.20+ 9000/8xx - HP/UX 10.30 (does not use HP native threads) The following configurations almost definitely won't work: 9000/7xx or 8xx - HP/UX 10.x where x < 2 9000/7xx or 8xx - HP/UX 9.x To install (everything, including server, client and development tools): /usr/sbin/swinstall -s mysql.full To install server only: /usr/sbin/swinstall -s mysql.server To install client pack only: /usr/sbin/swinstall -s mysql.client To install development tools only: /usr/sbin/swinstall -s mysql.developer The depot will place binaries/libraries in /opt/mysql and data in /var/opt/mysql. The depot will also create the appropriate entries in /sbin/init.d and /sbin/rc2.d to automatically start the server on boot. This obviously entails being root to install. Linking client libraries ------------------------ Clients have to be linked with: `-lmysqlclient' Problems running mysql_install_db ================================= It may happen that `mysql_install_db' doesn't install the privilige tables but ends with: Starting mysql server starting mysqld demon with databases from xxxxxx mysql demon ended In this case you should examine the log in the xxxxxx directory very carefully! This contains the reason why mysqld didn't start. If you can't understand what happens, you should at least include the log when you post a bug report using mysqlbug! Possible problems when running `mysql_install_db' are: `There is already a mysqld deamon running.' In this case you have probably don't have to run mysql_install_db at all. One only have to run mysql_install_db once when one install *MySQL* the first time. `Installing a second mysqld daemon doesn't work when one daemon is running.' The problem is the new server tries to use the same socket and port as the old one. You can start the new server with a different socket and port as follows: MYSQL_UNIX_PORT=/tmp/mysqld-new.sock MYSQL_TCP_PORT=3307 export MYSQL_UNIX_PORT MYSQL_TCP_PORT scripts/mysql_install_db After this you should edit your server boot script to start both daemon with different sockets and ports (safe_mysqld -socket=... -port=....). `mysqld crashes at once.' If you are running RedHat 5.0 and a glibc version before glibc 2.0.7-5 you should check that you have installed all glibc patches! There is a lot of information about this in the `MySQL' mail archives. *Note Linux:: `Can't connect to the server (when using mit-threads)' If `mysql_install_db' can't connect to the server you should check that you have an entry in `/etc/hosts' like: 127.0.0.1 localhost The above is only a problem on system that doesn't have a thread library and *MySQL* has to use mit-threads. `You don't have write access to create a socket file (in /tmp ?)' In this case you have to start mysqld manually and add the privilege information yourself. If you are using a binary version and are not installing in /usr/local/mysql, you have specify the paths mysqld should use with arguments. You can get information about which paths mysqld uses and the how to change them with `mysqld --help'. You can also specify paths for safe_mysqld by doing the following: MYSQL_UNIX_PATH=/some_directory_for_tmp_files/mysqld.sock MYSQL_TCP_PORT=3306 TMPDIR=/some_directory_for_tmp_files/ export MYSQL_UNIX_PATH MYSQL_TCP_PORT TMPDIR scripts/mysql_install_db or bin/mysqld --skip-grant bin/mysql -u root mysql After this you can execute the sql commands in mysql_install_db. `The paths may be different from what mysqld expects.' You can override all paths to mysqld with command line arguments. Use `mysqld --help' for more information. You can edit bin/safe_mysqld to reflect the paths for your installation. A simple test to see that everything is working is: `bin/mysqladmin version' Problems starting *MySQL* ========================= Check the log file to see if mysqld started up correctly. `mysqld' daemon starts with a cd to 'mysql-data-dir'. After this, mysqld-data-dir is changed to './' (current dir). All paths (databases, pid file, and log file) have this directory as base path './'. If you have any problems with wrong paths, try `mysqld --help' to see your current paths. Every path can be changed by a startup option to `safe_mysqld' or `mysqld' cd tail .log To verify that *MySQL* is working run the following tests: > cd /usr/local/bin > ./mysqlshow +-----------+ | Databases | +-----------+ | mysql | +-----------+ > ./mysqlshow mysql Database: mysql +--------+ | Tables | +--------+ | db | | host | | user | +--------+ > ./mysql -e "select host,db,user from db" mysql +------+--------+------+ | host | db | user | +------+--------+------+ | % | test | | | % | test_% | | +------+--------+------+ There is also a benchmark suite so you can compare how *MySQL* performs on different platforms. In the near future this will also be used to compare *MySQL* to other SQL databases. > cd bench > run-auto-increment-test You can also run the tests in the test subdirectory. To run `auto_increment.tst': ./mysql -vf test < ./tests/auto_increment.tst Expected results are shown in the file `./tests/auto_increment.res'. The safe_mysqld script is written that it should be able to start a source and a binary version of mysqld, even if these have sligtly different paths! You can install a binary release of MySQL anywhere as long as you start safe_mysqld from installation directory: cd mysql_installation_directory bin/safe_mysqld & If you want to change the startup options to mysqld you can always edit safe_mysqld! In this case you should copy safe_mysqld to some other location that it will not be overwritten if you sometimes decide to upgrade MySQL! Automatic start/stop of *MySQL* =============================== To start or stop *MySQL* use the following commands: scripts/mysql.server stop scripts/mysql.server start You might want to add these start and stop commands in the appropriate places in your `/etc/rc*' files when you start using *MySQL* for production applications. You can edit the mysql.server script to start safe_mysqld from some specific location and as some specific user. You can also add startup options to mysqld here. How standards compatible is *MySQL*? ************************************ What extensions has *MySQL* to ANSI SQL92? ========================================== The following are useful extensions in *MySQL* that you probably will not find in other SQL databases. Be warned that if you use them, your code will not be portable to other SQL servers. * The field types `MEDIUMINT', `SET', `ENUM' and the different `BLOB' and `TEXT' types. * The field attributes `AUTO_INCREMENT', `BINARY', `UNSIGNED' and `ZEROFILL'. * All string comparisons are by default are case independent with case according to ISO-8859-1 Latin1. If you don't like this you should declare your strings with the `BINARY' attribute. * *MySQL* maps all tables to filenames and with *MySQL* one can use standard system tools to backup, rename, move, delete and copy tables. This forces *MySQL* to be case sensitive on table names on operating systems that have case sensitive filenames (like most Unix systems). If you have a problem remembering table names, create everything in lowercase. * LIKE is allowed on numerical columns. * Use of `INTO OUTFILE' and `STRAIGHT_JOIN' in a `SELECT' statement. *Note Select::. * `EXPLAIN SELECT' to get a description on how tables are joined. * Use of index names, indexes on a subpart of a field, and use of `INDEX' or `KEY' in a `CREATE TABLE' statement. *Note Create table:: * Use of `DROP column' or `CHANGE column' in an `ALTER TABLE' statement. *Note Alter table::. * Use of `LOAD DATA INFILE'. This syntax is in many cases compatible with Oracle's `LOAD DATA INFILE'. *Note Load::. * Using `"' instead of `'' to enclose strings. * Using the escape `\' character. * The `SET OPTION' statement. *Note Set option:: * One doesn't have to have all columns in the `GROUP BY' part. *Note Group by functions:: * To make it easier for a user that comes from different SQL environments mysql supports a a lot of aliases for many functions. For example all string functions support both the ANSI SQL and the ODBC syntax. * The `||' and `&&' operators are, in *MySQL*, synonyms for `OR' and `AND', like in the C programming language. Likewise `|' and `&' stand for bitwise `OR' and `AND'. Because of this nice syntax, *MySQL* doesn't support the ANSI SQL operator `||' for string concatenation, one has to use `CONCAT()' instead. As `CONCAT()' takes any number of arguments it's easy to convert use of the `||' operator to *MySQL*. * Use of any of the following functions or commands: * `CREATE DATABASE' or `DROP DATABASE'. *Note Create database:: * `%' instead of mod(). `%' is supported for C programmers and for compatibility with PostgreSQL. * `=', `<>', `<=' ,`<', `>=',`>', `AND', `OR', or `LIKE' in a column statement * `LAST_INSERT_ID'. *Note mysql_insert_id:: * `REGEXP' or `NOT REGEXP'. * `CONCAT()' or `CHAR()' with one or more than two arguments. In *MySQL* the above functions can take any number of arguments. * `BIT_COUNT()', `ELT()', `FROM_DAYS()', `FORMAT()', `IF()', `PASSWORD()', `ENCRYPT()', `PERIOD_ADD()', `PERIOD_DIFF()', `TO_DAYS()', or `WEEKDAY()'. * Use of `TRIM' to trim substrings. ANSI SQL only supports removal of single characters. * The `STD()', `BIT_OR' and `BIT_AND' group functions. * Use of `MIN()' or `MAX()' as normal functions, not only group functions. * Use of `REPLACE' instead of `DELETE' + `INSERT'. *Note Replace:: What functionality is missing in *MySQL*. ========================================= The following functionality is missing in the current version of *MySQL*. For the priority of new extensions you should consult: The *MySQL* Todo list (http://www.tcx.se/Manual_split/manual_Todo.html). That is the latest version of the Todo list in this manual. *Note Todo::. Sub-selects ----------- The following will not work in *MySQL*: SELECT * from table WHERE id IN (SELECT id from table2) MySQL only supports `INSERT ... SELECT...' and `REPLACE ... SELECT...'. Independent sub-selects will be probably be available in 3.22.0. One can now use the function `IN()' in other context however. SELECT INTO TABLE ----------------- MySQL doesn't yet support `SELECT ... INTO TABLE...'. Currently MySQL only supports `SELECT ... INTO OUTFILE...', which is basicly the same thing.. Transactions ------------ Transactions are not supported. *MySQL* will shortly support atomic operations which is like transactions without rollback. With atomic operations you can make a bunch of insert/select/whatever commands and be guaranteed that no other thread will interfere. In this context you won't usually need rollback. Currently you can do this with the help of the `LOCK TABLES/UNLOCK TABLES' command. *Note Lock tables:: Triggers -------- Triggers are not supported. The planned update language will be able to handle stored procedures, but without triggers. Triggers usually slow down everything, even for queries when they aren't needed. Foreign Keys ------------ The `FOREIGN KEY' syntax in *MySQL* exists only for compatibility with other SQL vendors `CREATE TABLE' commands: It doesn't do anything. The `FOREIGN KEY' syntax without `ON DELETE ..' is mostly used for documentation purposes. Some ODBC applications may use this to produce automatic `WHERE' clauses though, but this is usually easy to override. `FOREIGN KEY' is sometimes used as a constraint check, but this check is in practice unnecessary if rows are inserted into the tables in the right order. *MySQL* only supports these commands because some application require them to exists (but not work!). In *MySQL* one can work around the problem that `ON DELETE ...' isn't implemented by adding the approative `DELETE' statement to the application when one deletes records from a table that has `FOREIGN KEY'. In practice this is as quick (in some case quicker) and much more portable than using `FOREIGN KEY'. Foreign keys are something that makes life very complicated, because the foreign key definition must be stored in a database and implementing them would mean that the whole 'nice approach' of using files that can be moved, copied and removed would be destroyed. In the near future we will extend `FOREIGN KEYS' so that at least the information will be saved and may be retrieved by mysqldump and ODBC. Some reasons NOT to use FOREIGN KEYS .................................... There are so many problems with the `FOREIGN KEY's that we don't know where to start. * The speed impact will be terrible when `INSERTING' and `UPDATING' records and in this case almost all `FOREIGN KEY' checks are useless because one usually inserts records in the right tables in the right order. * There will also be a need to hold locks on many more tables when updating one because the side effects can cascade trough the hole database. It's MUCH faster to first delete records from one table and subsequently delete them from the other tables. * One can't restore a table anymore by doing a full delete from the table and then restoring all records (from a new source or from a backup). * If you have foreign keys you can't dump and restore tables without doing this in a very specific order. * It's very easy to do 'allowed' circular definitions that make the tables impossible to recreate with a single create statement, even if the definition works and is usable. The only nice aspect of foreign key is that it gives ODBC and some other client programs the ability to see how a table is connected and use this to show connection diagrams and to help building applicatons. *MySQL* will soon store the `FOREIGN KEY' definitions so that a client can ask and receive an answer how the original connection was made. The current `.frm' file format does not have any place for it. Views ----- *MySQL* doesn't support views, but this is on the TODO. - as start of a comment ----------------------- Some other SQL databases have `--' as start comment. *MySQL* has `#' as the start comment character, even if the `mysql' command line tool removes all lines that starts with `--'. You can also use the C comment style `/* this is a comment */' with *MySQL*. *Note Comments:: *MySQL* will not support this degenerated comment style because we have had many problems with automatically generated SQL queries that have used something like the following code: UPDATE table_name SET credit=credit-!payment! Where instead of !payment! we automaticly insert the value of the payment. What do you think will happen when 'payment' is negative ? Because 1-1 is legal in SQL, we think is terrible that '-' means start comment. If you have a sql program in a textfile that contains `--' comments you should use: replace " --" " #" < text-file-with-funny-comments.sql | mysql database. instead of the normal mysql database < text-file-with-funny-comments.sql You can also change the `--' to `#' comments in the command file: replace " --" " #" -- text-file-with-funny-comments.sql Change them back with: replace " #" " --" -- text-file-with-funny-comments.sql What standards does *MySQL* follow? =================================== Entry level SQL92. ODBC level 0-2. What functions exist only for compatibility? ============================================ * `GRANT'. *Note Grant:: This always succeeds. You should use the MySQL privilege tables. *Note Privileges:: * `CREATE INDEX'. *Note Create Index:: This always succeeds. You should create your index with `CREATE TABLE'. *Note Create table:: You can also use `ALTER TABLE'. *Note Alter table::. * `DROP INDEX'. *Note Drop Index:: This always succeeds. You can use `ALTER TABLE' to drop indexes. *Note Alter table::. Limitations of `BLOB' and `TEXT' types ====================================== If you want to `GROUP BY' or `ORDER BY' on a `BLOB' or `TEXT' field, you must make the field into a fixed length object. The standard way to do this is with the `SUBSTRING' functions. If you don't do this only the first `max_sort_length' (default=1024) will considered when sorting. SELECT comment from table order by substring(comment,20); How to cope without COMMIT-ROLLBACK =================================== *MySQL* doesn't support COMMIT-ROLLBACK. The problem with COMMIT-ROLLBACK is that to handle this efficiently it would require a completely different table layout than *MySQL* uses today. *MySQL* would also need extra threads that do automatic cleanups on the tables and the disk usage would be much higher. This would make *MySQL* about 2-4 times slower than it is today. One of the reasons that *MySQL* is so much faster than almost all other SQL databases (typical times are at least 2-3 times faster) is the lack of COMMIT-ROLLBACK. For the moment, we are much more for implementing the SQL server language (someting like stored procedures). With this you would very seldom really need COMMIT-ROLLBACK. This would also give much better performance. Loops that need transactions can normally be coded with the help of `LOCK TABLES', and one doesn't need cursors when one can update records on the fly. We have transactions and cursors on the TODO but not quite prioritised. If it is implemented it will be as a option to `CREATE TABLE'. That means that COMMIT-ROLLBACK will only work on those tables and only those tables will be slower. We at TcX have a greater need for a real fast database than a 100% general database. Whenever we find a way to implement these without any speed loss we will probably do it. For the moment there are many more important things to do. Check the TODO for how we prioritise things at the moment. Customers with higher levels of support can alter this, so things may be reprioritised. The current problem is actually `ROLLBACK'. Without `ROLLBACK' you can do anything with `LOCK TABLES'. To support `ROLLBACK' *MySQL* would have to be changed to store all old records that were updated and revert everything back to the starting point if `ROLLBACK' was issued. For simple cases this isn't that hard to do (the current isamlog could be used for this), but if one wants to have `ROLLBACK' with `ALTER/DROP/CREATE TABLE' it would make everything much harder to implement. To avoid using `ROLLBACK' one can do: 1. `LOCK TABLES ...' 2. Test conditions. 3. Update if everything is ok. 4. `UNLOCK TABLES' This is usually much faster, but not always. The only thing this doesn't handle if someone does a kill on the process. One can also use functions to update things in one operation. By doing all updates relatively and/or only updating those fields that actually have changed one can get a very efficient application. For example, when we are doing updates on some customer information, we only update the customer data that has changed and only test that none of the changed data, or data that depends on the changed data, has changed in the original row. The test for change is done with the `WHERE' clause in the `UPDATE' statement. If the record wasn't updated we give the client a message: "Some of the data you have changed has been changed by another user", and then we show the old row versus the new row in a window. The user can then decide which version of the customer record he should use. This gives us something like 'column locking' but actually even better, because we only update some of the columns with relative information. This means that a typical update statement looks something like: UPDATE tablename SET pay_back=pay_back+'relative change' UPDATE customer set customer_date='current_date', address='new address', phone='new phone', money_he_owes_us=money_he_owes+'new_money' where customer_id=id and address='old address' and phone='old phone'; As you can see, this is very efficient and even if another client has changed the 'money_he_owes_us' or 'pay_back' amount this will still work. In many cases, users have wanted `ROLLBACK' and/or `LOCK TABLES' to manage unique identifiers for some tables. This can be handled much more efficiently by using an `AUTO_INCREMENT' column and the *MySQL* API function `mysql_insert_id'. *Note mysql_insert_id:: At TcX we have never had any need for row level locking as we have always been able to code around it. I know some cases that really need row locking, but they are very few. If you want to have row level locking you can do something like: UPDATE table_name SET row_flag=1 WHERE id=ID; MySQL returns `affected rows' = 1 if the row was found and row_flag wasn't 1 in the original document. On the TODO there is `GET_LOCK' and `RELEASE_LOCK' for those that want to implement application level locking. How do *MySQL* privileges work? ******************************* *MySQL* has an advanced but non-standard security/privilege system. What can the privilege system do. ================================= The basic function of the *MySQL* privilege system is to give a username on a host select, insert, update and delete privileges on a database. Extra functionality includes the ability to have a anonymous user and give permission to use *MySQL* specific funtions like `LOAD DATA INFILE'. Please note that the user names for a SQL database, like *MySQL*, has nothing to do with Unix users. As a convenience most *MySQL* clients tries to log in with the current user name, but this may be changed with the `--user' switch. This means that you can't in any way make a database secure without having passwords for all users. How does the privilege system work? =================================== In *MySQL* the combination of host and user is the unique identity. Don't think of users, think of host+user and everything should be much clearer. You can for example have a user named 'Robb' at two different hosts (with different privileges) in *MySQL* without any conflicts. The *MySQL* privilege system makes sure that each user may do exactly the things that they are supposed to be allowed to do. The system decides to grant different privileges depending on *which xuser* connects from *which host* to *which database*. You can always test your privileges with the script `mysqlaccess', which Yves Carlier has provided for the *MySQL* distribution. *Note Access denied:: *Note Security:: All privileges are stored in three tables. `user', `host' and `db'. Everything granted in the `user' table is valid for every database that cannot be found in the `db' table. For this reason, it might be wise to grant users (apart from superusers) privileges on a per-database basis only. The `host' table is mainly there to maintain a list of "secure" servers. At TcX `host' contains a list of all machines on the local network. These are granted all privileges. The connecting user's privileges are calculated by the following algorithm: 1. First sort the tables by: Table Sorted by host host without wild/hosts with wild/empty hosts db host without wild/hosts with wild/empty hosts user host/user Host by putting hosts without wildcards first, followed by hosts with wildcards and entries with `host = ""'. Within each host, sort by user using the same rules. Finally, in the `db' table, sort by db using the same rules. In the steps below, we will look through the sorted tables and *always use the first match found*. 2. Get the privileges for the connecting user from the `user' table using the first match found. Call this set of privileges PRIV. 3. Get the privileges for the connecting user from the `db' table using the first match found. 4. If `host = ""' for the entry found in the `db' table, AND PRIV with the privileges for the host in the `host' table, i.e. remove all privileges that are not "Y" in both. (If `host <> ""', PRIV is not affected. In such cases, `host' must have matched the connecting host's name at least partially. Therefore it can be assumed that the privileges found in this row match the connecting host's profile.) 5. OR (add) PRIV with the privileges for the user from the `user' table, i.e. add all privileges that are "Y" in `user'. *Remember that if you change the tables you must do a `mysqladmin reload' to make the changes take effect.* The connecting user gets the set of privileges PRIV. Let's show an example of the sorting and matching! Suppose that the user table contains this: +-----------+----------+- | Host | User | ... +-----------+----------+- | % | root | ... | % | jeffrey | ... | localhost | root | ... | localhost | | ... +-----------+----------+- Then the search order will be: * localhost/root * localhost/any * any/jeffrey * any/root So jeffrey attempting to connect on localhost will be matched by the `localhost/any' line, not by the `any/jeffrey' line. The first match found is used! So if you have access problems, print out the user table, sort it by hand, and see where the match is being made. Here follows an example to add a user 'custom' that can connect from hosts 'localhost', 'server.domain' and 'whitehouse.gov'. He wants to have password 'stupid'. The database 'bankaccount' he only want to use from 'localhost' and the 'customer' database he wants to be able to reach from all three hosts. shell> mysql mysql. mysql> insert into user (host,user,password) values('localhost','custom',password('stupid')); mysql> insert into user (host,user,password) values('server.domain','custom',password('stupid')); mysql> insert into user (host,user,password) values('whitehouse.gov','custom',password('stupid')); mysql> insert into db (host,db,user,Select_priv,Insert_priv,Update_priv,Delete_priv, Create_priv,Drop_priv) values ('localhost','bankaccount','custom','Y','Y','Y','Y','Y','Y'); mysql> insert into db (host,db,user,Select_priv,Insert_priv,Update_priv,Delete_priv, Create_priv,Drop_priv) values ('%','customers','custom','Y','Y','Y','Y','Y','Y'); You can of course also use xmysqladmin, mysql_webadmin, mysqladmin and even xmysql to insert/change and update values in the privilege tables. You can find these utilities in the Contrib directory. The privilege tables ==================== The grant tables privileges on rows are *select*, *insert*, *update* and *delete*. The table and database privileges are *create* and *drop*. Create and drop are for both tables and databases. Since a user with a drop grant can delete any table, this is the same thing as a drop grant for the database. Other privileges give the right to use files (for `LOAD DATA INFILE' and `SELECT INTO OUTFILE') and to use the administrative commands *shutdown*, *reload*, *refresh* and *process*. The privilege system is based on 3 tables. `user' table Contains all host+user combinations that are allowed to connect to the mysql server, together with their optional passwords. The `user' table has the following columns: Field Type Key Default Host char(60) PRI "" User char(16) PRI "" Password char(16) - "" Select_priv enum('N','Y') - N Insert_priv enum('N','Y') - N Update_priv enum('N','Y') - N Delete_priv enum('N','Y') - N Create_priv enum('N','Y') - N Drop_priv enum('N','Y') - N Reload_priv enum('N','Y') - N Shutdown_priv enum('N','Y') - N Process_priv enum('N','Y') - N File_priv enum('N','Y') - N `db' table Contains which databases a host+user is allowed to use, and what he can do with the tables in each database. The `db' table has the following columns: Field Type Key Default Host char(60) PRI "" Db char(64) PRI "" User char(16) PRI "" Select_priv enum('N','Y') - N Insert_priv enum('N','Y') - N Update_priv enum('N','Y') - N Delete_priv enum('N','Y') - N Create_priv enum('N','Y') - N Drop_priv enum('N','Y') - N `host' table Is only used in big networks as a lookup for empty host entries in the db table. This means that if you want a user to be able to use the database from all hosts in your network, you should put " as the host name in the db table. In this case the `host' table should contain a entry for every host in your network. The `host' table has the following columns: Field Type Key Default Host char(60) PRI "" Db char(64) PRI "" Select_priv enum('N','Y') - N Insert_priv enum('N','Y') - N Update_priv enum('N','Y') - N Delete_priv enum('N','Y') - N Create_priv enum('N','Y') - N Drop_priv enum('N','Y') - N * The HOST and DB columns may contain a string with the SQL wildcards `%' and `_'. Leaving any of these columns empty is equivalent to setting it to '%'. * A HOST may be `localhost', a hostname, an IP number or a string with wildcards. An empty host in the db table means any host in the host table. An empty host in the host or user table means *any host that can create a TCP connection to your server*. * A DB is the name of a database or an SQL regexp. * An empty USER column means any username will do. One can't have wildcards in the user name. * A user not matching anything in the `user' table will be processed as a no-name user. * The privileges from the user table are OR'ed to the `db' table. This means that a superuser only needs to be in the user table with all privilege-flags set to `Y'. You can use an entry like `123.444.444.%' in the host table to give every user on an IP C-net access. To avoid the possibility that somebody tries to fool this setup by naming a host `123.444.444.somewhere.com', *MySQL* disallows all hostnames that start with digits and a dot. So if your host is named something like `1.2.foo.com' it will never be allowed with name matching. Use the IP number in this case. Adding new user privileges to *MySQL* ===================================== To add privileges to the *MySQL* database: This assumes the current user has insert privileges for the mysql db table and reload privileges. The server (mysqld) has to be running. If it is not, start it with `safe_mysqld --log &'. > mysql mysql insert into user values ('%','monty',password('something'),'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y') ; insert into user (host,user,password) values('localhost','dummy','') ; insert into user values ('%','admin','','N','N','N','N','N','N','Y','N','Y','Y') ; quit > mysqladmin reload This makes three new users: `Monty' Full superuser, but must use password when using *MySQL*. `admin' Doesn't need a password but is only allowed to use `mysqladmin reload', `mysqladmin refresh' and `mysqladmin processlist'. May be granted individual database privileges through table `db'. `dummy' Must be granted individual database privileges through table `db'. Default privileges. =================== The default privileges (set in `scripts/mysql_install_db') let root do anything. Any user can do anything with any database whose name is 'test' or starts with 'test_'. A normal user can't use `mysqladmin shutdown' or `mysqladmin processlist'. See the script (`scripts/mysql_install_db') for an example on how to add other users. The privilege tables are read into mysqld with `mysqladmin reload'. A example of permission setup. ============================== A common mistake is to forget that passwords are stored encrypted, which leads to something like: `INSERT INTO user VALUES ('%','jeffrey','bLa81m0','Y','Y','Y','N','N','N','N','N', 'N','N');' Then (of course) a `mysqladmin reload' to make the authentication change take effect, then trying to connect to the server: $ ./mysql -h sqlserver -u jeffrey -p bLa81m0 test Access denied Try this instead: INSERT INTO user VALUES ('%','jeffrey',password('bLa81m0'),'Y','Y','Y','N','N','N','N','N','N','N'); As before, `mysqladmin reload' to make the authentication change take effect. Now things should work. Why do I get this `Access denied?' error. ========================================= * Have you installed the *MySQL* grant tables with the script `mysql_install_db'? Test by executing `mysql -u root test'. This should not give an error. You can also check if you have a file 'user.ISD' in the mysql database directory (ordinary install_dir/var/mysql/user.ISD). * One a fresh installation you should use 'mysql -u root mysql' to access the grant tables. * Remember that you have to do `mysqladmin reload' each time you change the grant tables. Otherwise the old tables are still used! * For testing, you should start the mysqld daemon with the `--without-grant-tables' option. Now you can change the *MySQL* grant tables and use the script `mysqlaccess' to check if your grant worked. `mysqladmin reload' tells the mysqld daemon to start using the new grant tables. * Even if you have access problems with perl, python, or ODBC, always test your privilege problems with `mysql -u user database' or `mysql -u user -ppassword database'. Please notice that there is no space between -p and the password. One can also use the `--password=your_password' syntax to give the password! * If you get the error 'Access denied' when trying to connect to the database with `mysql -u user database' then you have a problem with the 'user' table. Check this by doing `mysql -u root mysql' and `select * from user'. You should get an entry with 'hostname' and 'user' matching your computers hostname and your username. If the client and the server are running on the same host and you haven't used the `--host' option to mysql and you are not using MIT threads, 'localhost' is a synonym for your hostname. * The `Access denied' error message will tell you who you are trying to log in as, from which host you are trying to log in, and if you were using a password or not. You should normally have one entry in the `user' table that exactly matches your host and user, exactly as given in the error message. * If `mysql -u root test' works but `mysql -h your_hostname -u root test' gives 'Access denied' then you don't have the right name for your host in the user table. For example if you have an entry with host 'tcx' in the 'user' table, but your DNS tells *MySQL* that your hostname is 'tcx.subnet.se' then the entry will not work. Test by adding a record with the IP of your host in the 'user' table. You can, natuarally, also add a host with a wildcard (for example 'tcx%') in the 'user table' (but using hostnames ending with % is pretty insecure). * When using MIT threads, localhost is never used. All connections to the mysqld daemon is via TCP IP and you must have your real hostname in 'user' even if you are running the client on the same host as the server. * If you get the error 'Access to database denied' then you have a problem with the db table. If the used entry in the db table has an empty hostname, check also the corresponding entry in the 'host' table. * If `mysql -u user database' works on the server machine, but `mysql -u host -u user database' doesn't work on another client machine, then you don't have the client machine in the 'user' or the 'db' table. * If you can't get password to work, remember that passwords must be inserted with the PASSWORD function. *Note Privilege example:: * If `mysql -u user test' works but `mysql -u user other_database' doesn't work, you don't have the other_database in the 'db' table. * If you get 'Access to database denied' when using the `SELECT ... INTO OUTFILE' or `LOAD DATA' SQL commands then you probably don't have the `File_priv' privilege set for you in the user table. * If everything else fails, start the `mysqld' daemon with: `--debug=d,general,query'. This will print info about the host and user that tries to connect and also information about each command issued. *Note Debugging::. * If you have any other problems with the *MySQL* grant tables and feel you must post the problem to the list, always add a dump of the *MySQL* grant tables. You can dump the tables with the `mysqldump mysql' command. As always, post your problem with the `mysqlbug' script. * If you get the error `Can't connect to local mySQL server' or `Can't connect to MySQL server on some_hostname' this means that the daemon mysqld is not running or you are trying to connect to the wrong socket or port. Check that the socket exists (normally /tmp/mysql.sock) or try to connect to the port with telnet: `telnet hostname 3306'. You can also try `mysqladmin version' to get some more information. How to make MySQL secure against crackers. ========================================== To make a MySQL system secure you should think about the following: bullet Use passwords for all *MySQL* users. Remember that anyone can log in as any other person as simply as 'mysql -user other_user database'. This is common behaviour with all client/server applications. You can change the password of all users by editing the `mysql_install_db' script or only for the *MySQL* root user with: mysql -u root -e "update user set password=password('new_password') where user='root'" mysql bullet Don't start the *MySQL* deamon as root. mysqld can be run as any user. You can also add a new user 'mysql' to make everything even more crash-proof. You don't need to change the root user name in the 'user' table even if you run mysqld as another user, as *MySQL* user has nothing to do with Unix users. To start mysqld as another user, you can edit the mysql.server script to start mysqld as another user. Normally this is done with the 'su' command. bullet Check that only the mysqld user has read/write privileges to the database directories. bullet Don't give 'Process_priv' privileges to all users. Anyone can check if one changes a password with the 'mysqladmin processlist' command. mysqld saves an extra connection for a user with 'Process_priv' privileges so that a root user can log in and check things even if all normal connections are in use. bullet Don't give 'File_priv' to all users. If a user has this privilege he can write a file anywhere in the file system with the privileges of the mysqld daemon! To make this a bit safer, all files generated with `SELECT INTO OUTFILE' are generated readable by all and one can't overwrite existing files. bullet If you don't trust your DNS, you should use IP's instead of hostnames in the privilege tables. The -secure option to mysqld should in principle make hostnames safe. In any case one should be real careful about using wildcards with hostnames! bullet If you put a root password in the mysql.server script, you should make this only readable for root. The following options to `mysqld' affects security: `--secure' Check that the ip that was returned from `get_hostbyname' resolves back to the original hostname. This is done to make it harder for someone on the outside to get access by simulating another host. This options also adds some sanity checks of hostnames. This is turned off by default since it sometimes takes a long time to check this. `--skip-grant-tables' Do not use the privilege system att all. This gives everyone *full access* to all databases! `--skip-name-resolve' Hostnames are not resolved. All hostnames in the privilege tables must be IP-numbers or 'localhost'. `--skip-networking' Don't allow connections over the network (TCP/IP). All connections to mysqld are done with Unix sockets. This options doesn't work very good on systems that uses MIT-pthreads as MIT-pthreads doesn't support Unix sockets. *MySQL* language reference ************************** Literals. How do you write strings and numbers? =============================================== Strings ------- A string may have ' or " around it. \ is a escape character. The following escape characters are recognised: `\0' An ascii 0 character. `\n' A newline character. `\t' A tab character. `\r' A return character. `\b' A backspace character. `\'' A `'' character. `\"' A `"' character. `\\' A `\' character. `\%' A `%' character. This is used in wildcard strings to search for `%'. `\_' A `_' character. This is used in wildcard strings to search for `_'. A ' inside a string started with ' may be written as ''. A " inside a string started with " may be written as "". Some example selects that shows how it works. MySQL> select 'hello', "'hello'", '""hello""', '''h''e''l''l''o''', "hel""lo"; 1 rows in set (0.00 sec) +-------+---------+-----------+-------------+--------+ | hello | 'hello' | ""hello"" | 'h'e'l'l'o' | hel"lo | +-------+---------+-----------+-------------+--------+ | hello | 'hello' | ""hello"" | 'h'e'l'l'o' | hel"lo | +-------+---------+-----------+-------------+--------+ mysql> select 'hello', "hello", '""hello""', "'ello", 'e''l''lo', '\'hello'; 1 rows in set (0.00 sec) +-------+-------+-----------+-------+--------+--------+ | hello | hello | ""hello"" | 'ello | e'l'lo | 'hello | +-------+-------+-----------+-------+--------+--------+ | hello | hello | ""hello"" | 'ello | e'l'lo | 'hello | +-------+-------+-----------+-------+--------+--------+ mysql> select "This\nIs\nFour\nlines"; 1 rows in set (0.00 sec) +--------------------+ | This Is Four lines | +--------------------+ | This Is Four lines | +--------------------+ If you want to insert binary data into a blob the following characters must be represented by escape sequences: `\0' Ascii 0. Should be replaced with "\0" (A backslash and a 0 digit). `\' Ascii 92, backslash `'' Ascii 39, Single quote `"' Ascii 33, Double quote One doesn't have to escape `"' inside `'' and `"' inside `''. If you write C code you can use the C API function `mysql_escape_string(char *to,char *from,uint length)' to escape characters for the `INSERT' clause. (Note that 'to' must be at least 2 times bigger than from). In perl you can use the `quote' function. You should run the escape function on every possible string that may have a one of the above special characters! Numbers ------- Integers are just a sequence of digits. Floats use `.' as a decimal separator. Examples of valid numbers are: `1221', `294.42', `-32032.6809e+10'. `NULL' ------ When using the text file export formats, `NULL' may be represented by `\N'. *Note Load:: Database, table, index and column names --------------------------------------- Database, table, index and column names all follow the same rules in *MySQL*. A name may use alphanumeric characters from the default character set. This is by default ISO-8859-1 Latin1 but may be changed when compiling *MySQL*. Since *MySQL* needs to be able to decide if something is a name or a number the following special cases occurs. * A name can not consist of only numbers. * A name may start with a number. This is a difference from many other systems! * It is not recommended to use names like `1e'. This is because expressions like `1e+1' may be interpreted like the expression `1e + 1' or the number `1e+1'. Punctuation characters like `.' and `@' are not allowed in names since they will be used to extend *MySQL*. Column types. ============= The following column types are supported: * M means Max display size. * L means the actual length in a single row. * M means the maximum length. * D means the number of decimals. Name Description Size TINYINT[(M)] [UNSIGNED] A very small integer. Signed range 1 [ZEROFILL] -128 - 127. Unsigned range 0 - 255. SMALLINT[(M)]. [UNSIGNED] A small integer. Signed range -32768 2 [ZEROFILL] - 32767. Unsigned range 0 - 65535. MEDIUMINT[(M)] [UNSIGNED] A medium integer. Signed range 3 [ZEROFILL] -8388608-8388607. Unsigned range 0 - 16777215. INT[(M)] [UNSIGNED] A normal integer. Signed range 4 [ZEROFILL] -2147483648 - 2147483647. Unsigned range 0 - 4294967295. BIGINT[(M)] [UNSIGNED] A large integer. Signed range 8 [ZEROFILL] -9223372036854775808 - 9223372036854775807. Unsigned Range 0 - 18446744073709551615. Because all arithmetic is done with signed BIGINT or DOUBLE, one shouldn't use unsigned big integers bigger than 9223372036854775807 (63 bits) with anything else than bit functions! FLOAT(Precision) A small floating point number. 4 Precision can be 4 or 8. FLOAT(4) is a single precision number and FLOAT(8) is a double precision number (se the DOUBLE entry). This syntax is for ODBC compatibility. Range -3.402823466E+38F - -1.175494351E-38, 0, -1.175494351E-38 - 3.402823466E+38F. FLOAT[(M,D)] A small floating point number. 4 Cannot be unsigned. Range -3.402823466E+38F - -1.175494351E-38, 0, -1.175494351E-38 - 3.402823466E+38F. DOUBLE PRECISION[(M,D)] A normal floating point number. 8 Cannot be unsigned. Range -1.7976931348623157E+308 - -2.2250738585072014E-308, 0, 2.2250738585072014E-308 - 1.7976931348623157E+308. REAL[(M,D)] Same as DOUBLE 8 DECIMAL [(M,D)] An unpacked floating point number. M+D Cannot be unsigned. Currently the same range maximum range as a double. Behaves as a CHAR column NUMERIC [(M,D)] Same as DECIMAL M+D TIMESTAMP [(M)] An automatic timestamp. 4 DATE A type to store date information. 4 Uses the "YYYY-MM-DD" syntax, but may be updated with a number or a string. Understands at least the following syntaxes: 'YY-MM-DD', 'YYYY-MM-DD', and 'YYMMDD'. Range 0000-00-00 to 9999-12-31. TIME A type to store time information. 3 Uses the "HH:MM:SS" syntax, but may be updated with a number or a string. Understands at least the following syntaxes: 'HH:MM:SS, 'HHMMSS', 'HHMM', 'HH'. DATETIME A type to store date and time 8 information. Format "YYYY-MM-DD HH:MM:SS". Takes 8 bytes. Range '0000-01-01 00:00:00' - '9999-12-31 23:59:59'. CHAR(M) [binary] A fixed length string that is always M filled up with spaces to the specified length. Range 1 - 255 characters. All end space are removed when retrieved. Is sorted and compared case insensitively unless the binary keyword is given. VARCHAR(M) [binary] A variable length string that is L+1 stored with its length. All end space are removed when storing it. Maximum range 1 - 255 characters. Is sorted and compared case insensitively unless the binary keyword is given. TINYTEXT and TINYBLOB A `TEXT'/`BLOB' with max length of L+1 255 characters. TEXT and BLOB A `TEXT'/`BLOB' with max length of L+2 65535 characters. MEDIUMTEXT and MEDIUMBLOB A `TEXT'/`BLOB' with max length of L+3 16777216 characters. LONGTEXT and LONGBLOB A `TEXT'/`BLOB' with max length of L+4 4294967295 characters. ENUM('value','value2',...) A string object that can have only 1 or one set of allowed values (or NULL). 2 *Note Type details:: SET('value','value2',...) A string object that can have one or 1-8 many values of a set of allowed values. *Note Type details::. More about data types --------------------- Database size info. ................... In the above table L means the actual length of a instance and M the maximum length. So L+1 for "abcd" means 5 bytes in the database. If you use any data type with an L in the length field you will get a variable length record format. The numeric types ................. All integer types can have an optional argument `unsigned'. This can be used when you only want to allow positive numbers in the column or you need a little bigger numerical range for the column. Also for all integer columnsn, the optional argument `ZEROFILL' means that the column will be padded with zeroes up to the maximum length. Max display size and decimals are for formatting and calculation of maximum column width. When storing a value in an integer that is outside its range, *MySQL* stores the maximum (or minimum) possible value. When doing an `ALTER TABLE' or `LOAD DATA INFILE' one gets these conversions as 'warnings'. We have on the TODO to fix INSERT and UPDATE so they can return warnings, but this is scheduled for the next protocol change. For example when storing `-999999999999999' into an int column the value ends up as `-2147483648'. And `9999999999999999' ends up as `2147483647'. And if the `int' is unsigned the stored values above becomes `0' and `4294967296'. The same rules go for all other integer types. When returning data for an int(4) column that exceeds the allocated space, *MySQL* will return 9.99. If the operation is an `UPDATE' a warning will be issued. Note that a type like `decimal(4,2)' means maximum 4 characters with two decimal points. That gives a range between `-.99' -> `9.99'. To avoid some rounding problems, *MySQL* always rounds everything that it stores in any floating point column according to the number of decimals. This means that `2.333' stored into `float(8,2)' is stored as `2.33'. `TIMESTAMP' type ................ Has a range of 1 Dec 1970 time 0.00 to sometime in the year 2106 and a resolution of one second. A TIMESTAMP column will automatically be updated on `INSERT' and `UPDATE' statements if set to `NULL' or if the column is not updated in the statement. Can be (part of) an index. Note that if you have many timestamp columns in a row, then only the last timestamp column will be automatically updated. Any timestamp column will be set to the current time if set to `NULL'. Depending on the display size one gets one of the following formats: "YYYY-MM-DD HH:MM:SS", "YY-MM-DD HH:MM:SS", "YYYY-MM-DD" or "YY-MM-DD". `TEXT' and `BLOB' types ....................... These are objects that can have a variable length without upper limit. All TEXT and BLOB objects are stored with their length (saved in 1 to 4 bytes depending on the type of object). The maximum `TEXT' and `BLOB' length you can use is dependent on available memory and client buffers. The only differences between `TEXT' and `BLOB' is that `TEXT' is sorted and compared case insensitively while `BLOB' is compared case sensitively (by character values). `TEXT' and `BLOB' objects CANNOT be an index. A BLOB is a binary large object which can hold any amount of data. There are 4 kinds of blobs *Note Column types::. Normally one can regard a BLOB as a VARCHAR without a specified limit. `TEXT' is a `BLOB' that is sorted and compared case insensitively. A `BLOB'/`TEXT' column may not be bigger that the message buffer. Note that you have to change the message buffer on both the server and the client. *Note MySQL parameters::. `MyODBC' defines `BLOB's as `LONGVARBINARY' and `TEXT's as `LONGVARCHAR'. Restrictions for `BLOB' and `TEXT' columns: 1. A `BLOB' or `TEXT' cannot be an index or a part of an index 2. When one sorts or groups a `BLOB' or `TEXT', only the first `max_sort_length' (default 1024) of the blob is used. This value can be changed by the `-O' option when starting the mysqld daemon. One can group on an expression involving a `BLOB'/ `TEXT': `SELECT id,SUBSTR(blob,1,100) GROUP BY 2' 3. There is no end space truncation for `BLOB' and `TEXT' as there is for `CHAR' and `VARCHAR'. `ENUM' type ........... A string object that can have only one of a set of allowed values. The value to be stored may be given case independently. If one tries to store a non-existing value, "" is stored. If used in a number context this object returns/stores the value index. If there is less than 255 possible values this object occupies 1 byte, else two bytes (with a maximum of 65535 different values). Note that if an integer is put in the `ENUM' you get the corresponding string with the first counting as number 1. (0 is reserved for wrong enum values). Sorting on `ENUM' types are done according to the order of the strings in the enum. If declared `NOT NULL' the default value is the first value, else the default value is `NULL'. For example the column `test ENUM("one","two", "three")' can have any of these values: NULL "one" "two" "three" `SET' type .......... A string object that can have one or many values from a set of allowed values. Each value is separated by a ','. If used in a number context this object returns/stores the bit positions of the used values. This object occupies (number_of_different_values-1)/8+1 bytes, rounded up to 1,2,3,4 or 8. One can't have more than 64 different values. Note that if an integer is put in the `SET' you get the corresponding string with the first bit corresponding to the first string. Sorting on `SET' types are done numerically. For example the column `test SET("one","two") NOT NULL' can have any of these values: "" "one" "two" "one,two" Normally on SELECT on a SET column with LIKE or FIND_IN_SET(): SELECT * from banner where banner_group LIKE '%value%'; SELECT * from banner where FIND_IN_SET('value',banner_group)>0; But the following will also work: SELECT * from banner where banner_group = 'v1,v2'; ;Exact match SELECT * from banner where banner_group & 1; ;Is in first group Choosing the right type for a column. ------------------------------------- Try to use the most precise type in all cases. For example for an integer between 1-99999 a `unsigned mediumint' is the best type. A common problem is representing monetary values accurately. In *MySQL* you should use the `DECIMAL' type. This is stored as a string so no loss of accuracy should occur. If accuracy is not to too important the `DOUBLE' type may also be good enough. For high precision you can always convert to a fixed point type stored in a `BITINT'. This allows you to do all calculations with integers and only convert the result back to floating point. *Note Row format::. Column indexes -------------- You can have indexes on all *MySQL* columns except `BLOB' and `TEXT' types. Using indexes on the relevant columns is the best way to improve the performance of selects. For `CHAR' and `VARCHAR' columns you can have an index on a prefix. The example below shows how to create an index for the first 10 characters of a column. This is much faster and requires less disk space than having an index on the whole column. CREATE TABLE test ( name CHAR(200) NOT NULL, KEY index_name (name(10)); Multiple column indexes ----------------------- *MySQL* can have one index on parts of different columns. A multiple-column index can be considered a sorted array where the columns are concatenated. This makes for fast queries where the first column in the index is a known quantity and the other columns are not. Suppose that you have a table: CREATE TABLE test ( id INT NOT NULL, last_name CHAR(30) NOT NULL, first_name CHAR(30) NOT NULL, PRIMARY KEY (id), INDEX name (last_name,first_name)); Then the index `name' is an index over last_name and first_name. The `name' index will be used in the following queries: SELECT * FROM test WHERE last_name="Widenius"; SELECT * FROM test WHERE last_name="Widenius" AND first_name="Michael"; SELECT * FROM test WHERE last_name="Widenius" AND (first_name="Michael" OR first_name="Monty"); SELECT * FROM test WHERE last_name="Widenius" and first_name >="M" and first_name < "N"; The `name' index will NOT be used in the following queries: SELECT * FROM test WHERE first_name="Michael"; SELECT * FROM test WHERE last_name="Widenius" or first_name="Michael"; Type mapping to ease moving table definitions between different databases engines --------------------------------------------------------------------------------- To support easier use of code from different SQL vendors, *MySQL* does supports the following mappings: binary(num) char(num) binary char varying varchar float4 float float8 double int1 tinyint int2 smallint int3 mediumint int4 int int8 bigint long varbinary blob long varchar text middleint mediumint varbinary(num) varchar(num) binary Functions for use in `SELECT' and `WHERE' clauses ================================================= A `select_expression' or `where_definition' can consist of any expression using the following functions: In the examples below the output of the `mysql' program has been shortened. So this: mysql> select mod(29,9); 1 rows in set (0.00 sec) +-----------+ | mod(29,9) | +-----------+ | 2 | +-----------+ Has been converted to: mysql> select mod(29,9); -> 2 Grouping functions. ------------------- `(' `)' Parenthesis. Force order of evaluation in a expression. mysql> select 1+2*3; -> 7 mysql> select (1+2)*3; -> 9 Normal arithmetic operations. ----------------------------- `+' Addition `-' Subtraction. `*' Multiplication `/' Division. A division by zero results in a `NULL'. mysql> select 102/(1-1); -> NULL Bit functions. -------------- These have a range of maximum 64 bits because *MySQL* uses bigint (64 bit) arithmetic. `|' Bitwise OR. mysql> select 29 | 15; -> 31 `&' Bitwise and. mysql> select 29 & 15; -> 13 `BIT_COUNT()' Number of set bits in an argument. mysql> select bit_count(29); -> 4 Logical operations. ------------------- All logical function return 1 (TRUE) or 0 (FALSE). `NOT' `!' Logical NOT. Return 1 if argument is 0 else return 0. mysql> select NOT 1; -> 0 mysql> select NOT NULL; -> NULL mysql> select ! (1+1); -> 0 mysql> select ! 1+1; -> 1 `OR' `||' Logical OR. Return 1 if any of the arguments are non 0 and not NULL. mysql> select 1 || 0; -> 1 mysql> select 0 || 0; -> 0 mysql> select 1 || NULL; -> 1 `AND' `&&' Logical AND. Return 1 if all of the arguments are non 0 or NULL mysql> select 1 && NULL; -> 0 mysql> select 1 && 0; -> 0 Comparison operators. --------------------- Returns 1 (TRUE), 0 (FALSE) or `NULL'. These functions work for both numbers and strings. *MySQL* uses the following rules to decide how the compare is done: * If both arguments to a compare operation are strings, compare as strings. * If both arguments are integers, compare as integers. * If one of the arguments is a `TIMESTAMP' or `DATETIME' column and the other argument is a constant. In this case the constant is converted to a timestamp before the comparasion. This is to be more ODBC friendly. * In all other cases compare as floating point numbers (real). If one or both of the arguments are `NULL' the result of the comparison is `NULL'. `=' Equal. mysql> select 1 = 0; -> 0 mysql> select '0' = 0; -> 1 mysql> select '0.0' = 0; -> 1 mysql> select '0.01' = 0; -> 0 mysql> select '.01' = 0.01; -> 1 `<>' `!=' Not equal. mysql> select '.01' <> '0.01'; -> 1 mysql> select .01 <> '0.01'; -> 0 mysql> select 'zapp' <> 'zappp'; -> 1 `<=' Smaller than or equal. mysql> select 0.1 <= 2; -> 1 `<' Smaller than. mysql> select 2 <= 2; -> 1 `>=' Bigger than or equal. mysql> select 2 >= 2; -> 1 `>' Bigger than. mysql> select 2 > 2; -> 0 `ISNULL(A)' Returns 1 if `A' is `NULL' else 0. mysql> select isnull(1+1); -> 0 mysql> select isnull(1/0); -> 1 `A BETWEEN B AND C' `A' is bigger or equal as `B' and `A' is smaller or equal to `C'. Does the same thing as `(A >= B AND A <= C)' if all arguments are of the same type. It's the first argument (`A') that decides how the comparison should be done! If `A' is a string expression, compare as case insensitive strings. If `A' is a binary string, compare as binary strings. If `A' is an integer expression compare as integers, else compare as reals. mysql> select 1 between 2 and 3; -> 0 mysql> select 'b' between 'a' and 'c'; -> 1 mysql> select 2 between 2 and '3'; -> 1 mysql> select 2 between 2 and 'x-3'; -> 0 String comparison functions. ---------------------------- `expr IN (value,...)' Returns 1 if expr is any of the values in the `IN' list, else it returns 0. If all values are constants, then all values are evaluated according to the type of expr and sorted. The search for the item is then done by using a binary search. This means `IN' is very quick when used with constants in the `IN' part. mysql> select 2 in (0,3,5,'wefwf'); -> 0 mysql> select 'wefwf' in (0,3,5,'wefwf'); -> 1 `expr NOT IN (value,...)' Same as `NOT (expr IN (value,...))' `expr LIKE expr' SQL simple regular expression comparison. Returns 1 (TRUE) or 0 (FALSE). With `LIKE' you have two wild characters. `%' Matches any number of characters, even zero characters. `_' Matches exactly one character. `\%' Matches one `%'. `\_' Matches one `_'. mysql> select 'David!' like 'David_'; -> 1 mysql> select 'David!' like 'David\_'; -> 0 mysql> select 'David_' like 'David\_'; -> 1 mysql> select 'David!' like '%D%v%'; -> 1 mysql> select 10 like '1%'; -> 1 `LIKE' is allowed on numerical expressions! (Extension) `expr NOT LIKE expr' Same as `NOT (expr LIKE expr)'. `expr REGEXP expr' Checks string against extended regular expr. *Note Regexp::. NOTE: Because *MySQL* uses the C escape syntax in strings (`\n') You must double any `'\'' that you uses in your REGEXP strings. mysql> select 'Monty!' regexp 'm%y%%'; -> 0 mysql> select 'Monty!' regexp '.*'; -> 1 mysql> select 'new*\n*line' regexp 'new\\*.\\*line' `expr NOT REGEXP expr' Same as `NOT (expr REGEXP expr)'. `STRCMP()' Returns 0 if the strings are the same. Otherwise return -1 if the first argument is smaller according to the current sort-order, otherwise return 1. mysql> select strcmp('text', 'text2'); -> -1 mysql> select strcmp('text2', 'text'); -> 1 mysql> select strcmp('text', 'text'); -> 0 Control flow functions. ----------------------- `IFNULL(A,B)' If `A' is not `NULL' it returns `A', else `B'. mysql> select ifnull(1,0); -> 1 mysql> select ifnull(0,10); -> 0 mysql> select ifnull(1/0,10); -> 10 `IF(A,B,C)' If `A' is true (`A <> 0' and `A <> NULL') then return `B', else return `C'. A is evaluated as an INTEGER, which means that if you are using floats you should also use a comparison operation. mysql> select if(1>2,2,3); -> 3 Mathematical functions. ----------------------- All mathematical functions returns `NULL' in the case of a error. `-' Sign. Changes sign of argument. mysql> select - 2; -> -2 `ABS()' Absolute value. mysql> select abs(2); -> 2 mysql> select abs(-32); -> 32 `SIGN()' Sign of argument. Returns -1, 0 or 1. mysql> select sign(-32); -> -1 mysql> select sign(0); -> 0 mysql> select sign(234); -> 1 `MOD()' `%' Modulo (like % in C). mysql> select mod(234, 10); -> 4 mysql> select 253 % 7; -> 1 mysql> select mod(29,9); -> 2 `FLOOR()' Largest integer value not greater than x. mysql> select floor(1.23); -> 1 mysql> select floor(-1.23); -> -2 `CEILING()' Smallest integer value not less than x. mysql> select ceiling(1.23); -> 2 mysql> select ceiling(-1.23); -> -1 `ROUND(N)' Round argument `N' to an integer. mysql> select round(-1.23); -> -1 mysql> select round(-1.58); -> -2 mysql> select round(1.58); -> 2 `ROUND(Number,Decimals)' Round argument `Number' to a number with `Decimals' decimals. mysql> select ROUND(1.298, 1); -> 1.3 `EXP(N)' Returns the value of `e' (the base of natural logarithms) raised to the power of `N'. mysql> select exp(2); -> 7.389056 mysql> select exp(-2); -> 0.135335 `LOG(X)' Return the natural logarithm of `X'. mysql> select log(2); -> 0.693147 mysql> select log(-2); -> NULL `LOG10(X)' return the base-10 logarithm of `X'. mysql> select log10(2); -> 0.301030 mysql> select log10(100); -> 2.000000 mysql> select log10(-100); -> NULL `POW(X,Y)' `POWER(X,Y)' Return the value of `X' raised to the power of `Y'. mysql> select pow(2,2); -> 4.000000 mysql> select pow(2,-2); -> 0.250000 `sqrt(X)' Returns the non-negative square root of `X'. mysql> select sqrt(4); -> 2.000000 mysql> select sqrt(20); -> 4.472136 `PI()' Return the value of PI. mysql> select PI(); -> 3.141593 `COS(X)' Return the cosine of `X', where `X' is given in radians. mysql> select cos(PI()); -> -1.000000 `SIN(X)' Return the sine of `X', where `X' is given in radians. mysql> select sin(PI()); -> 0.000000 `TAN(X)' Returns the tangent of `X', where `X' is given in radians. mysql> select tan(PI()+1); -> 1.557408 `ACOS(X)' Return the arc cosine of `X'; that is the value whose cosine is `X'. If `X' is not in the range -1 to 1 `NULL' is returned. mysql> select ACOS(1); -> 0.000000 mysql> select ACOS(1.0001); -> NULL mysql> select ACOS(0); -> 1.570796 `ASIN(X)' Return the arc sine of `X'; that is the value whose sine is `X'. If `X' is not in the range -1 to 1 `NULL' is returned. mysql> select ASIN(0.2); -> 0.201358 mysql> select ASIN('foo'); -> 0.000000 `ATAN(X)' Return the arc tangent of `X'; that is the value whose tangent is `X'. mysql> select ATAN(2); -> 1.107149 mysql> select ATAN(-2); -> -1.107149 `ATAN2(X,Y)' Return the arc tangent of the two variables `X' and `Y'. It is similar to calculating the arc tangent of `Y / X', except that the signs of both arguments are used to determine the quadrant of the result. mysql> select ATAN(-2,2); -> -0.785398 mysql> select ATAN(PI(),0); -> 1.570796 `COT(N)' Return the cotangens of `N'. mysql> select COT(12); -> -1.57267341 mysql> select COT(0); -> NULL `RAND([X])' Returns a random float, `0 <= x <= 1.0', using the integer expression `X' as the optional seed value. mysql> SELECT RAND(); -> 0.5925 mysql> SELECT RAND(20); -> 0.1811 mysql> SELECT RAND(20); -> 0.1811 mysql> SELECT RAND(); -> 0.2079 mysql> SELECT RAND(); -> 0.7888 One can't do a ORDER BY on a column with RAND() values because ORDER BY would evaluate the column multiple times. `MIN(X,Y...)' Min value of arguments. Must have 2 or more arguments, else these are `GROUP BY' functions. The arguments are compared as numbers. If no records are found `NULL' is returned. mysql> SELECT MIN(2,0); -> 0 mysql> SELECT MIN(34,3,5,767); -> 3 mysql> SELECT MIN(a) from table where 1=0; -> NULL `MAX(X,Y...)' Max value of arguments. Must have 2 or more arguments, else these are `GROUP BY' functions. The arguments are compared as numbers. If no records are found `NULL' is returned. mysql> SELECT MAX(34,3,5,767); -> 767 mysql> SELECT MAX(2,0,4,5,34); -> 34 mysql> SELECT MAX(a) from table where 1=0; -> NULL `DEGREES(N)' Return `N' converted from radians to degrees. mysql> select DEGREES(PI()); -> 180.000000 `RADIANS(N)' Return `N' converted from degrees to radians. mysql> select RADIANS(90); -> 1.570796 `TRUNCATE(Number, Decimals)' Truncate number `Number' to `Decimals' decimals. mysql> select TRUNCATE(1.223,1); -> 1.2 mysql> select TRUNCATE(1.999,1); -> 1.9 mysql> select TRUNCATE(1.999,0); -> 1 String functions. ----------------- `ASCII(S)' Returns the ASCII code value of the leftmost character of `S'. If `S' is `NULL' return `NULL'. mysql> SELECT ascii(2); -> 50 mysql> SELECT ascii('dx'); -> 100 `CHAR(X,...)' Returns a string that consists of the characters given by the ASCII code values of the arguments. `NULLs' are skipped. mysql> SELECT char(77,121,83,81,'76'); -> 'MySQL' `CONCAT(X,Y...)' Concatenates strings. May have more than 2 arguments. mysql> SELECT CONCAT('My', 'S', 'QL'); -> 'MySQL' `LENGTH(S)' `OCTET_LENGTH(S)' `CHAR_LENGTH(S)' `CHARACTER_LENGTH(S)' Length of string. mysql> SELECT length('text'); -> 4 mysql> SELECT octet_length('text'); -> 4 `LOCATE(A,B)' `POSITION(B IN A)' Returns position of `A' substring in `B'. The first position is 1. Returns 0 if `A' is not in `B'. mysql> select locate('bar', 'foobarbar'); -> 4 mysql> select locate('xbar', 'foobar'); -> 0 `INSTR(A,B)' Returns position of first substring `B' in string `A'. This is the same as `LOCATE' with swapped parameters. mysql> select instr('foobarbar', 'bar'); -> 4 mysql> select instr('xbar', 'foobar'); -> 0 `LOCATE(A,B,C)' Returns position of first substring `A' in string `B' starting at `C'. mysql> select locate('bar', 'foobarbar',5); -> 7 `LEFT(str,length)' Gets length in characters from beginning of string. mysql> select left('foobarbar', 5); -> 'fooba' `RIGHT(A,B)' `SUBSTRING(A FROM B)' Gets `B' characters from end of string `A'. mysql> select right('foobarbar', 5); -> 'arbar' mysql> select substring('foobarbar' from 5); -> 'arbar' `LTRIM(str)' Removes space characters from the beginning of string. mysql> select ltrim(' barbar'); -> 'barbar' `RTRIM(str)' Removes space characters from the end of string. mysql> select rtrim('barbar '); -> 'barbar' `TRIM([[ BOTH | LEADING | TRAILING] [ A ] FROM ] B)' Returns a character string with all `A' prefixes and/or suffixes removed from `B'. If `BOTH', `LEADING' and `TRAILING' isn't used `BOTH' are assumed. If `A' is not given, then spaces are removed. mysql> select trim(' bar '); -> 'bar' mysql> select trim(leading 'x' from 'xxxbarxxx'); -> 'barxxx' mysql> select trim(both 'x' from 'xxxbarxxx'); -> 'bar' mysql> select trim(trailing 'xyz' from 'barxxyz'); -> 'barx' `SOUNDEX(S)' Gets a soundex string from `S'. Two strings that sound 'about the same' should have identical soundex strings. A 'standard' soundex string is 4 characters long, but this function returns an arbitrary long string. One can use `SUBSTRING' on the result to get a 'standard' soundex string. All non alpha characters are ignored in the given string. All characters outside the A-Z range are treated as vocals. mysql> select soundex('Hello'); -> 'H400' mysql> select soundex('Bдttre'); -> 'B360' mysql> select soundex('Quadratically'); -> 'Q36324' `SUBSTRING(A, B, C)' `SUBSTRING(A FROM B FOR C)' `MID(A, B, C)' Returns substring from `A' starting at `B' with `C' chars. The variant with `FROM' is ANSI SQL 92 syntax. mysql> select substring('Quadratically',5,6); -> ratica `SUBSTRING_INDEX(String, Delimiter, Count)' Returns the substring from `String' after `Count' `Delimiters'. If `Count' is positive the strings are searched from left else if count is negative the substrings are searched and returned from right. mysql> select substring_index('www.tcx.se', '.', 2); -> 'www.tcx' mysql> select substring_index('www.tcx.se', '.', -2); -> 'tcx.se' `SPACE(N)' Return a string of `N' spaces. mysql> select SPACE(6); -> ' ' `REPLACE(A, B, C)' Replaces all occurrences of string `B' in string `A' with string `C'. mysql> select replace('www.tcx.se', 'w', 'Ww'); -> 'WwWwWw.tcx.se' `REPEAT(String, Count)' Repeats `String' `Count' times. If `Count <= 0' returns a empty string. If `String' or `Count' is `NULL' or `LENGTH(string)*count > max_allowed_size' returns `NULL'. mysql> select repeat('MySQL', 3); -> 'MySQLMySQLMySQL' `REVERSE(String)' Reverses all characters in string. mysql> select reverse('abc'); -> 'cba' `INSERT(Org, Start, Length, New)' Replaces substring in `Org' starging at `Start' and `Length' long with `New'. First position in `Org' is numbered 1. mysql> select insert('Quadratic', 3, 4, 'What'); -> 'QuWhattic' `INTERVAL(N, N1, N2, N3...)' It is required that `Nn' > `N3' > `N2' > `N1' is this function shall work. This is because a binary search is used (Very fast). Returns 0 if `N' < `N1', 1 if `N' < `N2' and so on. All arguments are treated as numbers. mysql> select INTERVAL(23, 1, 15, 17, 30, 44, 200); -> 3 mysql> select INTERVAL(10, 1, 10, 100, 1000); -> 2 mysql> select INTERVAL(22, 23, 30, 44, 200); -> 0 `ELT(N, A1, A2, A3...)' Returns `A1' if `N' = 1, `A2' if `N' = 2 and so on. If `N' is less than 1 or bigger than the number of arguments `NULL' is returned. mysql> select elt(1, 'ej', 'Heja', 'hej', 'foo'); -> 'ej' mysql> select elt(4, 'ej', 'Heja', 'hej', 'foo'); -> 'foo' `FIELD(S, S1, S2, S3...)' Returns index of `S' in `S1', `S2', `S3'... list. The complement of `ELT()'. Return 0 when S is not found. mysql> select FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo'); -> 2 mysql> select FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo'); -> 0 `FIND_IN_SET(string,string of strings)' Returns a value 1 to N if the 'string' is in 'string of strings'. A 'string of strings' is a string where each different value is separated with a ','. If the first argument is a constant string and the second is a column of type SET, the FIND_IN_SET is optimized to use bit arithmetic! mysql> SELECT FIND_IN_SET('b','a,b,c,d') -> 2 This function will not work properly if the first argument contains a ','. `LCASE(A)' `LOWER(A)' Changes `A' to lower case according to current character set ,dmappings (Default Latin1). mysql> select lcase('QUADRATICALLY'); -> 'quadratically' `UCASE(A)' `UPPER(A)' Changes `A' to upper case. mysql> select ucase('Hej'); -> 'HEJ' Date and time functions. ------------------------ Some examples using more than one date function: Select all record with a date_field from the last 30 days. SELECT something FROM table WHERE TO_DAYS(NOW()) - TO_DAYS(date_field) <= 30; A `Date' expression may be a date string, a datetime string, a timestamp([6 | 8 | 14]) or a number of format `YYMMDD' or `YYYYMMDD'. In a date expression a year may be 2 or 4 digits. 2 digits is assumed to be in the range 1970-2069. Dates 100-199 is converted to 2000-2999 to make year arithmetic easier! The special date '0000-00-00' can be stored and retrieved as 0000-00-00. A `Time' expression may be a date string, a datetime string, a timestamp([6 | 8 | 14]) or a number of format `HHMMSS' or `YYYYMMDDHHMMSS'. `DAYOFWEEK(date expr)' Gets weekday for `Date' (1 = Sunday, 2 = Monday, 2 = Tuesday ..) This is according to the ODBC standard. mysql> select dayofweek('1998-02-03'); -> 3 `WEEKDAY(date expr)' Gets weekday for `Date' (0 = Monday, 1 = Tuesday ..) mysql> select WEEKDAY('1997-10-04 22:23:00'); -> 5 mysql> select WEEKDAY('1997-11-05'); -> 2 `DAYOFMONTH(date expr)' Returns day of month (1-31) mysql> select DAYOFMONTH('1998-02-03'); -> 3 `DAYOFYEAR(date expr)' Returns day of year (1-366) mysql> select DAYOFYEAR('1998-02-03'); -> 34 `MONTH(date expr)' Returns month (1-12) mysql> select MONTH('1998-02-03'); -> 02 `DAYNAME(date expr)' Returns the name of the day. mysql> select dayname("1998-02-05"); -> Thursday `MONTHNAME(date expr)' Returns the name of the month. mysql> select monthname("1998-02-05"); -> February `QUARTER(date expr)' Returns quarter (1-4). mysql> select QUARTER('98-04-01'); -> 2 `WEEK(date expr)' Returns week (1-53) on locations where Sunday is the first day of the year mysql> select WEEK('98-02-20'); -> 7 `YEAR(date expr)' Returns year (1000-9999). mysql> select YEAR('98-02-03'); -> 1998 `HOUR(time expr)' Returns hour (0-23) mysql> select HOUR('10:05:03'); -> 10 `MINUTE(time expr)' Returns minute (0-59). mysql> select MINUTE('98-02-03 10:05:03'); -> 5 `SECOND(time expr)' Returns seconds (1000-9999). mysql> select SECOND('10:05:03'); -> 3 `PERIOD_ADD(P, N)' Adds `N' months to period `P' (of type `YYMM' or `YYYYMM'). Returns `YYYYMM'. mysql> select PERIOD_ADD(9801,2); -> 199803 `PERIOD_DIFF(A, B)' Returns months between periods `A' and `B'. `A' and `B' should be of format `YYMM' or `YYYYMM'. mysql> select PERIOD_DIFF(9802,199703); -> 11 `TO_DAYS(Date)' Changes a `Date' to a daynumber (Number of days since year 0). `Date' may be a `DATE' string, a `DATETIME' string, a `TIMESTAMP([6 | 8 | 14])' or a number of format `YYMMDD' or `YYYYMMDD'. mysql> select TO_DAYS(9505); -> 733364 mysql> select TO_DAYS('1997-10-07); -> 729669 `FROM_DAYS()' Changes a daynumber to a DATE. mysql> select from_days(729669); -> 1997-10-07 `DATE_FORMAT(Date, Format)' Formats the `Date' (a date or a timestamp) according to the `Format' string. The following format commands are known: M Month name W Weekday name D Day of the month with english suffix Y Year with 4 digits y Year with 2 digits a Abbreviated weekday name (Sun..Sat) d Day of the month, numeric m Month, numeric b Abbreviated month name (Jan.Dec) j Day of year (001..366) H Hour (00..23) k Hour ( 0..23) h Hour (01..12) I Hour (01..12) l Hour ( 1..12) i Minutes, numeric r Time, 12-hour (hh:mm:ss [AP]M) T Time, 24-hour (hh:mm:ss) S Seconds (00..59) s Seconds (00..59) p AM or PM w Day of the week (0=Sunday..) All other characters are copied to the result. mysql> select date_format('1997-10-04 22:23:00', 'W M Y h:i:s'); -> 'Saturday October 1997 22:23:00' mysql> select date_format('1997-10-04 22:23:00', 'D y a d m b j H k I r T S w'); -> '4th 97 Sat 04 10 Oct 277 22 22 10 10:23:00 PM 22:23:00 00 6' `TIME_FORMAT(time expr, format)' This can be used like the DATE_FORMAT above, but only with the format options which handle hours, minutes and seconds. Other options give NULL value or 0. `CURDATE()' `CURRENT_DATE()' Returns today's date. In form `YYYYMMDD' or `'YYYY-MM-DD'' depending on whether `CURDATE()' is used in a number or string context. mysql> select CURDATE(); -> '1997-12-15' mysql> select CURDATE()+0; -> 19971215 `CURTIME()' `CURRENT_TIME()' Returns the current time in the form `HHMMSS' or `'HH:MM:SS'', depending on whether `CURTIME()' is used in a number or string context. mysql> select CURTIME(); -> '23:50:20' mysql> select CURTIME()+0; -> 235026 `NOW()' `SYSDATE()' `CURRENT_TIMESTAMP()' Returns the current time. In format `YYYYMMDDHHMMSS' or `'YYYY-MM-DD HH:MM:SS'' depending on whether `NOW()' is used in a number or string context. mysql> select NOW(); -> '1997-12-15 23:51:26' mysql> select NOW()+0; -> 19971215235131 `UNIX_TIMESTAMP([date expression])' If called without any arguments, a unix timestamp (seconds in GMT since 1970.01.01 00:00:00). Normally it is called with a `TIMESTAMP' column as an argument in which case it returns the columns value in seconds. `Date' may also be a date string, a datetime string, or a number of format YYMMDD or YYYMMDD in local time. mysql> select UNIX_TIMESTAMP(); -> 882226357 mysql> select UNIX_TIMESTAMP('1997-10-04 22:23:00'); -> 875996580 `FROM_UNIXTIME(Unix_timestamp)' Returns a string of the timestamp in `YYYY-MM-DD HH:MM:SS' or `YYYYMMDDHHMMSS' format depending on context (numeric/string). mysql> select FROM_UNIXTIME(875996580); -> '1997-10-04 22:23:00' `FROM_UNIXTIME(Unix_timestamp, Format_string)' Returns a string of the timestamp formated according to the Format_string. The format string may contain: `M' Month, textual `W' Day (of the week), textual `D' Day (of the month), numeric plus english suffix `Y' Year, numeric, 4 digits `y' Year, numeric, 2 digits `m' Month, numeric `d' Day (of the month), numeric `h' Hour, numeric `i' Minutes, numeric `s' Seconds, numeric `w' Day (of the week), numeric All other All other characters are just copied. mysql> select FROM_UNIXTIME(UNIX_TIMESTAMP(), 'Y D M h:m:s x'); -> '1997 23rd December 03:12:30 x' `SEC_TO_TIME(Seconds)' Returns the hours, minutes and seconds of the argument in `H:MM:SS' or `HMMSS' format depending on context. mysql> select SEC_TO_TIME(2378); -> '00:39:38' mysql> select SEC_TO_TIME(2378)+0; -> 3938 `TIME_TO_SEC(Time)' Converts `Time' to seconds. mysql> select TIME_TO_SEC('22:23:00'); -> 80580 mysql> select TIME_TO_SEC('00:39:38'); -> 2378 Miscellaneous functions. ------------------------ `DATABASE()' Returns current database name. mysql> select DATABASE(); -> 'test' `USER()' `SYSTEM_USER()' `SESSION_USER()' Returns current user name. mysql> select USER(); -> 'davida' `PASSWORD(String)' Calculates a password string from plaintext password `String'. This must be used to store a password in the 'user' grant table. mysql> select PASSWORD('badpwd'); -> '7f84554057dd964b' `ENCRYPT(String[, Salt])' Crypt `String' with the unix `crypt()' command. The `Salt' should be a string with 2 characters. If `crypt()' was not found `NULL' will always be returned. `LAST_INSERT_ID()' Returns the last automatically generated value that was set in an auto_increment column. *Note mysql_insert_id::. mysql> select LAST_INSERT_ID(); -> 1 `FORMAT(Nr, Num)' Formats number `Nr' to a Format like '#,###,###.##' with `Num' decimals. mysql> select FORMAT(12332.33, 2); -> '12,332.33' `VERSION' Return the version of the *MySQL* server. mysql> select version(); -> '3.21.16-beta-log' `GET_LOCK(String,timeout)' Tries to get a lock on named 'String' with a timeout of 'timeout' seconds. Returns 1 if one got the lock, 0 on timeout and NULL on error (like out of memory or if thread was killed with `mysqladmin kill'. A lock is released if one executes `RELEASE_LOCK', executes a new `GET_LOCK' or if the thread ends. This function can be used to implement application locks or simulate record locks. mysql> select get_lock("automaticly released",10); -> 1 mysql> select get_lock("test",10); -> 1 mysql> select release_lock("test"); -> 1 mysql> select release_lock("automaticly released") -> NULL `RELEASE_LOCK(String)' Releases a lock this thread has got with `GET_LOCK'. Returns 1 if the lock was released, 0 if lock wasn't locked by this thread and NULL if the lock 'String' didn't exist. Functions for `GROUP BY' clause. -------------------------------- `COUNT(Expr)' Count number of non `NULL' rows. `count(*)' is optimised to return very quickly if no other column is used in the `SELECT'. select count(*) from student; select count(if(length(name)>3,1,NULL)) from student; `AVG(expr)' Average value of expr. `MIN(expr)' `MAX(expr)' Minimum/Maximum value of expr. `min()' and `max()' may take a string argument and will then return the minimum/maximum string value. `SUM(expr)' Sum of expr. `STD(expr)' `STDDEV(expr) (Oracle format)' Standard derivative of expression. This is a extension to `ANSI SQL'. `BIT_OR(expr)' The bitwise `OR' of all bits in expr. Calculation done with 64 bit precision. `BIT_AND(expr)' The bitwise `AND' of all bits in expr. Calculation done with 64 bit precision. MySQL has extended the use of `GROUP BY'. You can use columns or calculations in the `SELECT' expressions which don't appear in the `GROUP BY' part. This stands for 'any possible value for this group'. By using this, one can get a higher performance by avoiding sorting and grouping on unnecessary items. For example, in the following query one doesn't need to group on b.name: SELECT a.id,b.name,COUNT(*) from a,b WHERE a.id=b.id GROUP BY a.id In ANSI SQL you would have to add the customer.name in the `GROUP BY' for the following query. In *MySQL* the name redundant. SELECT order.custid,customer.name,max(payments) from order,customer WHERE order.custid = customer.custid GROUP BY order.custid; Note that you can't use expressions in the `GROUP BY' or `ORDER BY' clause. You can on the other hand use an alias on a expression and use this to solve the problem: SELECT id,FLOOR(value/100) AS val FROM table_name GROUP BY id,val ORDER BY val Create database syntax. ======================= CREATE DATABASE database_name Creates a database with the given name. The name can only contain letters, numbers or the `'_'' character. The max length of the database name is 32 characters. All databases in *MySQL* are directories, so a CREATE DATABASE only creates a directory in the *MySQL* database directory. You can also create databases with `mysqladmin'. *Note Programs:: Drop database syntax. ===================== DROP DATABASE database_name Drop all tables in the database and deleted the database. *You have to be VERY carefull with this command!* `DROP DATABASE' returns how many files was removed from the directory. Normally this is number of tables*3. You can also drop databases with `mysqladmin'. *Note Programs:: CREATE TABLE syntax. ==================== CREATE TABLE table_name ( create_definition,... ) create_definition: column_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT] [ PRIMARY KEY ] [reference_definition] or PRIMARY KEY ( index_column_name,... ) or KEY [index_name] KEY( index_column_name,...) or INDEX [index_name] ( index_column_name,...) or UNIQUE [index_name] ( index_column_name,...) or FOREIGN KEY index_name ( index_column_name,...) [reference_definition] or CHECK (expr) type: TINYINT[(length)] [UNSIGNED] [ZEROFILL] or SMALLINT[(length)] [UNSIGNED] [ZEROFILL] or MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL] or INT[(length)] [UNSIGNED] [ZEROFILL] or INTEGER[(length)] [UNSIGNED] [ZEROFILL] or BIGINT[(length)] [UNSIGNED] [ZEROFILL] or REAL[(length,decimals)] [UNSIGNED] [ZEROFILL] or DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL] or FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL] or DECIMAL[(length,decimals)] [UNSIGNED] [ZEROFILL] or NUMERIC[(length,decimals)] [UNSIGNED] [ZEROFILL] or CHAR(length) [BINARY], or VARCHAR(length) [BINARY], or DATE or TIME or TIMESTAMP or DATETIME or TINYBLOB or BLOB or MEDIUMBLOB or LONGBLOB or TINYTEXT or TEXT or MEDIUMTEXT or ENUM(value1,value2,value3...) or SET(value1,value2,value3...) index_column_name: column_name [ (length) ] reference_definition: REFERENCES table_name [( index_column_name,...)] [ MATCH FULL | MATCH PARTIAL] [ ON DELETE reference_option] [ ON UPDATE reference_option] reference_option: RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT *Note Column types:: The FOREIGN KEY, CHECK and REFERENCE syntax are only for compatibility. (To make it easier to port code from other SQL servers and run applications that create tables with references). They don't actually do anything. *Note Missing functions:: If a column doesn't have a DEFAULT value and is not declared as NOT NULL, the default value is NULL. * ZEROFILL means that number is pre-zeroed to maximal length. With `INT(5) ZEROFILL' a value of 5 is retrieved as `00005'. * `BINARY' means that the column will be compared case sensitive. The default is that all strings are compared case insensitive according to ISO-8859-1 Latin1. `BINARY' is 'sticky' which means that if a column marked `BINARY' is used in a expression, the whole expression is compared `BINARY'. * KEY is a synonym for INDEX. * UNIQUE is in MySQL a key that can only have distinct values. You will get an error if you try add a new row with a key that matches an old row. * PRIMARY KEY is a unique KEY. One can only have one PRIMARY KEY in a table. * If one doesn't assign a name to an index, the index will get the same name as the first key_column with an optional _# to make it unique. * Index columns and timestamp columns can't be NULL. For these columns the NULL attribute is silently removed. * With `column_name(length)' syntax one can specify an index which is only a part of a `string' column. This can make the index file much smaller. * A number column may have the additional attribute AUTO_INCREMENT to automatically get the largest value+1 for each insert where column value is NULL or 0. *Note mysql_insert_id:: * One can insert NULL for timestamp and auto_increment columns. This results in the current time / the next number. * Blob columns can't be index. * When one groups on a blob only the first 'max_sort_length' bytes are used. *Note BLOB Limitations::. * Deleted records are in a linked list and subsequent inserts will reuse old positions. To get smaller files one can use the `isamchk' utility to reorganise tables. * Each null column takes one bit extra, rounded up to the nearest byte. * The maximum record length can be calculated as follows: 1+ sum_of_column_lengths + null_columns/8 + number of variable length columns. * In some cases an attribute may silently change after creation: `VARCHAR' columns with a length of one or two are changed to `CHAR'. When using one `VARCHAR' column all `CHAR' columns longer than 2 are changed to `VARCHAR''s. This doesn't affect the usage of the column in any way; In *MySQL* `VARCHAR' is just a different way to store characters. `MySQL' does the conversion because it will save space and make the table faster. *Note Row format:: * On `INSERT'/`UPDATE' all strings (`CHAR' and `VARCHAR') are silently chopped/padded to the maximal length given by CREATE. All end spaces are also automatically removed. For example `VARCHAR(10)' means that the column can contain strings with a length up to 10 characters. * Something/0 gives a `NULL' value. * The regular expression function (`REGEXP' and `RLIKE') uses ISO8859-1 (Latin1) when deciding the type of a character. ALTER TABLE syntax ================== ALTER [IGNORE] TABLE table_name alter_spec [, alter_spec ...] alter_specification: ADD [COLUMN] create_definition or CHANGE [COLUMN] old_column_name create_definition or ALTER [COLUMN] column_name { SET DEFAULT literal | DROP DEFAULT } or ADD INDEX [index_name] ( index_column_name,...) or ADD UNIQUE [index_name] ( index_column_name,...) or DROP [COLUMN] column_name or DROP PRIMARY KEY or DROP INDEX key_name or RENAME [AS] new_table_name * `ALTER TABLE' works by creating a temporary table and copying all information to it and then the old table is deleted and the new one is renamed. This is done in such a way that all updates are automatically redirect to the new table without any failed updates. While the `ALTER TABLE' is working, the old table is readable for other clients. Table updates/writes to the table are stalled and only executed after the new table is ready. * If `IGNORE' isn't specified then the copy will be aborted and rolled back if there exists any duplicated unique keys in the new table. In case of duplicates the first found row will be used. This is a *MySQL* extension. * The `CHANGE column_name', `DROP column_name' and `DROP INDEX' are *MySQL* extensions to ANSI SQL92. * The optional word `COLUMN' is a pure noise word and can be omitted. * The `ADD' and `CHANGE' takes the same create_definition as `CREATE TABLE'. *Note Create table::. * `ALTER COLUMN' sets a new default value or removes the old default value for a column. * `DROP INDEX' removes an index. This is a *MySQL* extension. * The `FOREIGN KEY' syntax in *MySQL* exists only for compatibility. *Note Missing functions:: * If one drops a column_name which is part of some index, this index part is removed. If all index parts are removed then the index is removed. * `DROP PRIMARY KEY' drops index named `PRIMARY' or if no such index exists, it drops the first `UNIQUE' index in the table. * `CHANGE' tries to convert data to the new format as good as possible. * With `mysql_info(MYSQL*)' one can retrieve how many records were copied and how many records were deleted because of multiple indexes. * To use `ALTER TABLE' one needs select, insert, delete, update, create and drop privileges on the table. * If one uses `ALTER TABLE table_name RENAME AS new_name' without any other options, *MySQL* will only do a fast rename of table table. Some examples of using ALTER TABLE: CREATE TABLE t1 (a INTEGER,b CHAR(10)); INSERT INTO t1 VALUES(1,"testing"); ALTER TABLE t1 RENAME t2; ALTER TABLE t2 CHANGE a a TINYINT NOT NULL, CHANGE b c CHAR(20); ALTER TABLE t2 ADD d TIMESTAMP; ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a); ALTER TABLE t2 DROP COLUMN c; ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT, ADD INDEX (c); DROP TABLE t2; DROP TABLE syntax. ================== `DROP TABLE table_name [, table_name...]' Removes one or more tables. All the data and the definition are *removed* so take it easy with this command! DELETE syntax. ============== `DELETE FROM table_name WHERE where_definition' Returns records affected. If one does a delete without a `WHERE' clause then the table is recreated, which is much faster than doing a delete for each row. In these cases, the command returns zero as affected records. *MySQL* can't return the number of deleted row because the recreate is done without opening the data files to make sure that one can recreate the table as long as the table definition file `table_name.frm' is valid. SELECT syntax ============= `SELECT [STRAIGHT_JOIN] [DISTINCT | ALL] select_expression,... [INTO OUTFILE 'file_name' ...] [ FROM table_references [WHERE where_definition ] [GROUP BY column,...] [HAVING where_definition] [ ORDER BY column [ASC | DESC] ,..] [LIMIT [offset,] rows] [PROCEDURE procedure_name]] ' All used keywords must come in exactly the above order. For example a `HAVING' clause must come after any `GROUP BY' and before any `ORDER BY' clause. Strings are automatically converted to numbers and numbers to strings when needed (a-la Perl). If in a compare operation (`(=, <>, <= ,<, >=, >)') either of the arguments are numerical, the arguments are compared as numbers, else the arguments are compared as strings. All string comparisons are by default done case-independent by ISO8859-1 (The Scandinavian letter set which also works excellently with English). select 1 > '6x'; -> 0 select 7 > '6x'; -> 1 select 0 > 'x6'; -> 0 select 0 = 'x6'; -> 1 - A column name does not need a table prefix if the given column name is unique. - A select expression may be given an alias which will be its column name and can be used when sorting and grouping or in the `HAVING' clause. select concat(last_name,' ',first_name) as name from table order by name - Table_references is a list of tables to join. This may also contain `LEFT OUTER JOIN' references. *Note Join:: - In `LIKE' expressions % and _ may be preceded with '\' to skip the wildcard meaning and get a literal % or _. - A DATE is a string with one of the following syntaxes: - YYMMDD (Year is assumed to be 2000 if YY < 70.) - YYYYMMDD - YY.MM.DD Where '.' may be any non-numerical separator. - YYYY.MM.DD Where '.' may be any non-numerical separator. - `IFNULL()' and `IF()' return number or string value according to use. - `ORDER' and `GROUP' columns may be given as column names, column aliases or column numbers in `SELECT' clauses. - The `HAVING' clause can take any column or alias in the select_expressions. It is applied last, just before items are sent to the client, without any optimisation. Don't use it for items that should be in the WHERE clause. You can't write (yet): `SELECT user,MAX(salary) FROM users GROUP BY user HAVING max(salary)>10' Change it to: `SELECT user,MAX(salary) AS sum FROM users GROUP BY user HAVING sum > 10' - `STRAIGHT_JOIN' forces the optimiser to join the tables in the same order that the tables are given in the `FROM' clause. One can use this to get a query to be done more quickly if the optimiser joins the tables in non-optimal order. *Note Explain:: - LIMIT takes one or two numerical arguments. * If one argument, the argument indicates the maximum number of rows in a result. * If two arguments, the first argument says the offset to the first row to return, the second is the maximum number of rows. - INTO OUTFILE 'filename' writes the given set to a file. The file can not already exist from before. *Note Load::. Join syntax =========== *MySQL* supports the following `JOIN' syntaxes: table_reference, table_reference table_reference [CROSS] JOIN table_reference table_reference LEFT [OUTER] JOIN table_reference ON conditional-expr table_reference LEFT [OUTER] JOIN table_reference USING (column-commalist) table_reference NATURAL LEFT [OUTER] JOIN table_reference { oj table_reference LEFT OUTER JOIN table_reference ON conditional-expr } The last example is ODBC syntax. * A table reference may be aliased with `table_reference AS alias' or `table_reference alias'. * `,' and `JOIN' are semantically identical. This does a full join between the used tables. One normally specifies in the `WHERE' condition how the tables should be linked. * The `ON' conditional is any `WHERE' conditional. If there is no matching record for the right table in a `LEFT JOIN' a row with all columns set to NULL will be used for the right table. * The `USING' column-list is a list of fields that must exists in both tables. `A LEFT JOIN B USING (C1,C2,C3...)' is defined to be semantically identical to using an `ON' expression ` A.C1=B.C1 AND A.C2=B.C2 AND A.C3=B.C3... '. * The `NATURAL LEFT JOIN' of two tables is defined to be semantically identical to a `USING' with all column names that exist in both tables. * The last `LEFT JOIN' syntax exists only for compatibility with ODBC. INSERT syntax ============= INSERT INTO table [ (column_name,...) ] VALUES (expression,...) or INSERT INTO table [ (column_name,...) ] SELECT ... An expression may use any previous column in column_name list (or table if no column name list is given). The following holds for a multi-row `INSERT' statement: - The query cannot contain an `ORDER BY' clause. - The target table of the `INSERT' statement cannot appear in the FROM clause of the query. - If one uses `INSERT INTO ... SELECT ...' then one can get the following info string with the C API function `mysql_info()'. `Records: 100 Duplicates: 0 Warnings: 0' Duplicates are rows which couldn't be written because some index would be duplicated. Warnings are columns which were set to NULL, but have been declared NOT NULL. These will be set to their default value. In this case it's also forbidden in ANSI SQL to SELECT from the same table that you are inserting into. The problem that there may be problems if the SELECT finds records that is inserted at the same run. When using sub selects the situation could easily be very confusing! - If one sets a time stamp value to anything other than NULL, the time stamp value will be copied to the result table. - Auto increment columns works as usual. REPLACE syntax ============== REPLACE INTO table [ (column_name,...) ] VALUES (expression,...) or REPLACE INTO table [ (column_name,...) ] SELECT ... This works exactly like `INSERT', except that if there was some old record in the table with the same unique index the old record or records will be deleted before this record is inserted. *Note Insert::. LOAD DATA INFILE syntax ======================= `LOAD DATA INFILE' 'text_file_name.text' [`REPLACE' | `IGNORE'] `INTO' `TABLE' table_name [`FIELDS' [`TERMINATED BY' ',' [`OPTIONALLY'] `ENCLOSED BY' '"' `ESCAPED BY' '\\' ]] [`LINES TERMINATED BY' '\n'] [(Field1, Field2...)] This is used to read rows from a text file, which must be located on the server, at a very high speed. The server-client protocol doesn't yet support files over a connection. If you only have the file on the client, use *rcp* or *ftp* to copy it, possibly compressed, to the server before using `LOAD DATA INFILE'. All paths to the text file are relative to the database directory. To write data to a text file, use the `SELECT ... INTO OUTFILE 'interval.txt' fields terminated by ',' enclosed by '"' escaped by '\\' lines terminated by '\n' FROM ...' syntax. Normally you don't have to specify any of the text file type options. The default is a compact text file with columns separated with `tab' characters and all rows end with a newline. Tabs, newlines and `\' inside fields are prefixed with a `\'. NULLs are read and written as \N. `FIELDS TERMINATED BY' has the default value of `\t'. `FIELDS [OPTIONALLY] ENCLOSED BY' has the default value of `'''. `FIELDS ESCAPED BY' has the default value of `'\\''. `LINES TERMINATED BY' has the default value of `'\n''. `FIELDS TERMINATED BY' and `LINES TERMINATED BY' may be more than one character. If `LINES TERMINATED BY' is an empty string and `FIELDS TERMINATED BY' is non-empty then lines are also terminated with `FIELDS TERMINATED BY'. If `FIELDS TERMINATED BY' and `FIELDS ENCLOSED BY' both are empty strings (`''') then this gives a fixed row format ("not delimited" import format). With a fixed row size NULL values are output as a blank string. If you specify `OPTIONALLY' in `ENCLOSED BY', then only strings are enclosed in `ENCLOSED BY' by the `SELECT ... INTO' statement. Duplicated `ENCLOSED BY' chars are removed from strings that start with `ENCLOSED BY'. For example: With `ENCLOSED BY '"'': "The ""BIG"" boss" -> The "BIG" boss The "BIG" boss -> The "BIG" boss If `ESCAPED BY' is not empty then the following characters will be prefixed with the escape character: `ESCAPED BY', `ASCII 0', and the first character in any of `FIELDS TERMINATED BY', `FIELDS ENCLOSED BY' and `LINES TERMINATED BY'. If `FIELDS ENCLOSED BY' is not empty then `NULL' is read as a `NULL' value. If `FIELDS ESCAPED BY' is not empty then `\N' is also read as a `NULL' value. If `REPLACE' is used, then the new row will replace all rows which have the same unique index. If `IGNORE' is used, the row will then be skipped if a record already exists with an identical unique key. If none of the above options are used an error will be issued. The rest of the text file will be ignored if one gets a duplicate index error. Some possible cases that are not supported by `LOAD DATA': * Fixed size rows (`FIELDS TERMINATED BY' and `FIELDS ENCLOSED BY' both are empty) and BLOB columns. * If some of the separators are a prefix of another. * `FIELDS ESCAPED BY' is empty and the data contains `LINES TERMINATED BY' or `FIELDS ENCLOSED BY' followed by `FIELDS TERMINATED BY'. All rows are read into the table. If a row has too few columns, the rest of the columns are set to default values. `TIMESTAMP' columns are only set to the current time if there is a NULL value for the column or if the `TIMESTAMP' column is left out from the field list when the field list is used. For security reasons the text file must either reside in the database directory or be readable by all. Each user that wants to use `LOAD DATA INFILE' must also have 'Y' in the 'File_priv' column in the user privilege table! *Note Privileges:: Because `LOAD DATA INFILE' regards all input as strings you can't use number values for `enum' or `set' columns as you can with `INSERT' statements. All `enum' and `set' must be given as strings! For more information about the escaped syntax, *Note Base Syntax::. When the `LOAD DATA' query is done, one can get the following info string with the C API function `mysql_info()'. `Records: 1 Deleted: 0 Skipped: 0 Warnings: 0' Warnings are incremented for each column which can't be stored without loss of precision, for each column which didn't get a value from the read text line (happens if the line is too short) and for each line which has more data than can fit into the given columns. A warning is also given for any time, date, timestamp or datetime column that is set to 0. An example that loads all columns: LOAD DATA INFILE 'persondata.text' INTO TABLE persondata; *Note Table efficiency:: UPDATE syntax ============= UPDATE table SET column=expression,... WHERE where_definition All updates are done from left to right. If one accesses a column in the expression, update will then use the current value (a given value or the default value) of the column. UPDATE persondata SET count=count+1 SHOW syntax. Get information about tables, columns... ===================================================== SHOW DATABASES [LIKE wild] or SHOW TABLES [FROM database] [LIKE wild] or SHOW COLUMNS FROM table [FROM database] [LIKE wild] or SHOW INDEX FROM table [FROM database] or SHOW STATUS or SHOW VARIABLES [LIKE wild] Gives information about databases, tables or columns. If the `LIKE wild' part is used the `wild' string is a normal SQL wildcard (with % and _). `FIELDS' may be used as an alias for `COLUMNS' and `KEYS' may be used as an alias for `INDEXES'. `STATUS' gives status information from the server like `mysqladmin status'). The output may differ from the following: `Uptime' `Running_threads' `Questions' `Reloads' `Open_tables' 119 1 4 1 3 `VARIABLES' shows the values of the some of MySQL system variables. Most of these variables can be changed by different options to `mysqld'! EXPLAIN syntax. Get information about a SELECT. =============================================== EXPLAIN SELECT select_options Gives information about how and in which order tables are joined. With the help of `EXPLAIN' one can see when one has to add more indexes to tables to get a faster select that uses indexes to find the records. You can also see if the optimiser joins the tables in an optimal order. One can force the optimiser to use a specific join order with the `STRAIGHT_JOIN' option to select. The different join types are: `system' The table has only one record (= system table) `const' The table has at most one matching record which will be read at the start of the query. All columns in this table will be regarded as constants by the rest of the optimiser. `eq_ref' One record will be read from this table for each combination of the previous tables. `ref' All rows with matching indexes will be read from this table for each combination of the previous tables. `range' Only rows that is in a given index range will be retrieved trough an index. The extra column will tell which index is used. `all' A full table scan will be done for each combination of the previous tables. Here is a example of a join which is optimised with the help of `EXPLAIN'. EXPLAIN SELECT tt.TicketNumber, tt.TimeIn, tt.ProjectReference, tt.EstimatedShipDate, tt.ActualShipDate, tt.ClientID, tt.ServiceCodes, tt.RepetitiveID, tt.CurrentProcess, tt.CurrentDPPerson, tt.RecordVolume, tt.DPPrinted, et.COUNTRY, et_1.COUNTRY, do.CUSTNAME FROM tt, et, et AS et_1, do WHERE tt.SubmitTime Is Null and tt.ActualPC = et.EMPLOYID and tt.AssignedPC = et_1.EMPLOYID and tt.ClientID = do.CUSTNMBR; The `EXPLAIN' returns the following: table type possible_keys key key_len ref rows Extra et ALL PRIMARY NULL NULL NULL 74 do ALL PRIMARY NULL NULL NULL 2135 et_1 ALL PRIMARY NULL NULL NULL 74 tt ALL AssignedPC,ClientID,ActualPC NULL NULL NULL 3872 range checked for each record (key map: 35) In this case *MySQL* is doing a full join for all tables! This will take quite a long time as the product of the number of rows in each table must be examined! So if all tables had 1000 records *MySQL* has to look at 1000^4 = 1000000000000 rows. If the tables are bigger you can only imagine how long it would take... In this case the first error is that *MySQL* can't yet use efficiently indexes on columns that are declared differently: (varchar() and char() are not different in this context) In this case `tt.ActualPC' is `char(10)' and `et.EMPLOYID' is `char(15)'. Fix: mysql> alter table tt change ActualPC ActualPC varchar(15); And the above explanation shows: table type possible_keys key key_len ref rows Extra tt ALL AssignedPC,ClientID,ActualPC NULL NULL NULL 3872 where used do ALL PRIMARY NULL NULL NULL 2135 range checked for each record (key map: 1) et_1 ALL PRIMARY NULL NULL NULL 74 range checked for each record (key map: 1) et eq_ref PRIMARY PRIMARY 15 tt.ActualPC 1 Which is not perfect but much better. This version is executed in a couple of seconds. After mysql> alter table tt change AssignedPC AssignedPC varchar(15), change ClientID Clientid varchar(15); You get the following from `EXPLAIN': table type possible_keys key key_len ref rows Extra et ALL PRIMARY NULL NULL NULL 74 tt ref AssignedPC,ClientID,ActualPC ActualPC 15 et.EMPLOYID 52 where used et_1 eq_ref PRIMARY PRIMARY 15 tt.AssignedPC 1 do eq_ref PRIMARY PRIMARY 15 tt.Clientid 1 Which is 'almost' as good as it can get. The problem is that *MySQL* assumes that `tt.AcutalPC' is evenly distributed which isn't the case in the tt. Fortunately it is easy to tell *MySQL* about this: shell> isamchk --analyze PATH_TO_MYSQL_DATABASE/tt shell> mysqladmin refresh And now the join is 'perfect': table type possible_keys key key_len ref rows Extra tt ALL AssignedPC,ClientID,ActualPC NULL NULL NULL 3872 where used et eq_ref PRIMARY PRIMARY 15 tt.ActualPC 1 et_1 eq_ref PRIMARY PRIMARY 15 tt.AssignedPC 1 do eq_ref PRIMARY PRIMARY 15 tt.Clientid 1 DESCRIBE syntax. Get information about columns. =============================================== `(DESCRIBE | DESC) table [column]' Gives information about columns. This command is for Oracle compatibility. *Note Show::. Column may be a column name or a string. Strings may contain wild cards. `LOCK TABLES' syntax ==================== LOCK TABLES table_name [AS alias] READ|WRITE [, table_name READ|WRITE] ... UNLOCK TABLES Locks tables for this thread. If a thread has a READ lock on a table, the thread (and all other threads) can only read from the table. If a thread has a WRITE lock one a table, then only this thread can READ and WRITE on the table. All threads waits until they get all locks (no timeouts). When one uses `LOCK TABLES' one must lock all tables one is going to use! This policy ensures that table locking is deadlock free. LOCK TABLES trans READ, customer AS c WRITE SELECT SUM(value) FROM trans WHERE customer_id= #some_id#; UPDATE customer SET total_value=#value_from_last_statement# WHERE customer_id=#some_id# UNLOCK TABLES All tables are automatically unlocked when one issues another `LOCK TABLES' or if the connection to the server is closed. Normally you don't have to lock tables. There is a couple of cases when you would like to lock tables anyway: * If you are going to run many operations on a bunch of tables, its much faster to lock the tables you are going to use. The downside is of course that no other thread can update a READ locked table and no other thread can read a WRITE locked table. * As `MySQL' doesn't support a transaction environment, you must use lock tables if you want to ensure that no other thread comes between a read and a update. For example the previous example requires `LOCK TABLES' to be safe! If one didn't use `LOCK TABLES' there is a change that someone inserts a new 'trans' row between the SELECT and UPDATE statements. * By using incremental updates (`UPDATE customer set value=value+new_value') or the LAST_INSERT_ID() function you can avoid using `LOCK TABLES' in many cases. You can also solve some cases by using user level locks: GET_LOCK() and RELEASE_LOCK(). These locks are saved in a hash table in the server and implemented with pthread_mutex for high speed. *Note Miscellaneous functions:: SET OPTION syntax. ================== SET [OPTION] SQL_VALUE_OPTION=value, ... The used options remain in effect for the whole current session. The different options are: `SQL_SELECT_LIMIT=value' The maximum number of records to return in any select. If a select has a limit clause it overrides this statement. The default value for a new connection is 'unlimited'. `SQL_BIG_TABLES= 0 | 1' If set to 1 then all temporary tables are stored on disk instead of in memory. This will be a little slower, but one will not get the error `The table ### is full' for big selects that require a big temporary table. The default value for a new connection is 0 (use in memory temporary tables). `SQL_BIG_SELECTS= 0 | 1' If set to 1 then *MySQL* will abort if a select is attempted that will probably take a very long time. This is useful when an erroneous `WHERE' statement has been issued. A big query is defined as a `SELECT' that will probably have to examine more than `max_join_size' rows. The default value for a new connection is 0 (which will allow all SELECT's). `CHARACTER SET character_set_name | DEFAULT' This maps all strings from and to the client with the given mapping. Currently the only option for character_set_name is `cp1251_koi8', but one can easily add new mappings by editing the file `mysql_source_directory/sql/convert.cc'. One can restore the default mapping by using `DEFAULT' as the character_set_name. `SQL_LOG_OFF= 0 | 1' If set to 1 then no logging will done to the standard log for this client if the client has process list privileges. This doesn't affect the update log! `TIMESTAMP= timestamp_value | DEFAULT' Set the time for this client. This is used to get the original timestamp if one uses the update log to restore rows. `LAST_INSERT_ID= #' Set the value to be returned from LAST_INSERT_ID(). This is stored in the update log when one uses LAST_INSERT_ID() in a command that updates a table. GRANT syntax. (Compatibility function). ======================================= GRANT (ALL PRIVILEGES | (SELECT, INSERT, UPDATE, DELETE, REFERENCES (column list), USAGE)) ON table TO user,... [WITH GRANT OPTION] This command doesn't do anything. It is only in *MySQL* for compatibility reasons. (To make it easier to port code from other SQL servers). Privileges in *MySQL* are handled with the *MySQL* grant tables. *Note Privileges:: CREATE INDEX syntax (Compatibility function). ============================================= `CREATE [UNIQUE] INDEX index_name ON table_name ( column_name,... )' This function doesn't do anything. It is only in *MySQL* for compatibility reasons. You can create a new index with `ALTER TABLE'. *Note Alter table:: DROP INDEX syntax (Compatibility function). =========================================== `DROP INDEX index_name' This always succeeds. You can drop an index with `ALTER TABLE'. *Note Alter table:: Comment syntax ============== *MySQL* supports the `# to end of line' and `/* multiple line */' comment styles. select 1+1; # This comment is to the end of line select 1 /* in-line-comment */ + 1; select 1+ /* This will be ignored */ 1; *MySQL* doesn't support the `--' ANSI SQL style comments. *Note Missing comments::. CREATE FUNCTION syntax ====================== CREATE FUNCTION RETURNS [string|real|integer] SONAME DROP FUNCTION User definable functions (UDF) is way to extend *MySQL* with new functions that works as native *MySQL* functions like `ABS()' and `concat()'. UDF's are written in C or C++ and require that dynamic loading works on the operating system. The source distribution includes the file `udf_example.cc' that defines 5 new functions. The functions name, type and shared library is saved in the new system table 'func' in the 'mysql' database. To be able to create new functions one must have write privilege for the database 'mysql'. If one starts *MySQL* with -skip-grant-tables, then UDF initialization will also be skipped. Each defined function may have a xxxx_init function and a xxxx_deinit function. The init function should alloc memory for the function and tell the main function about the max length of the result (for string functions), number of decimals (for double functions) and if the result may be a null value. If a function sets the 'error' argument to 1 the function will not be called anymore and mysqld will return NULL for all calls to this instanse of the function. All strings arguments to functions are given as string pointer + length to allow handling of binary data. Remember that all functions must be thread safe. This means that one is not allowed to alloc any global or static variables that changes! If one needs memory one should alloc this in the init function and free this on the __deinit function. A dynamicly loadable file should be compiled sharable (something like: `gcc -shared -o udf_example.so myfunc.cc'). You can easily get all switches right by doing: `cd sql ; make udf_example.o' Take the compile line that make writes, remove the '-c' near the end of the line and add -o udf_example.so to the end of the compile line. The resulting library (udf_example.so) should be copied to some dir searched by ld, for example /usr/lib. Some notes about the example functions: * Function `metaphon' returns a metaphon string of the string argument. This is something like a soundex string, but it's more tuned for English. * Function `myfunc_double' returns summary of codes of all letters of arguments divided by summary length of all its arguments. * Function `myfunc_int' returns summary length of all its arguments. * Function `lookup' returns the IP number for an hostname. * Function `reverse_lookup' returns the hostname for a IP number. The function may be called with a string "xxx.xxx.xxx.xxx" or four numbers. After the library is installed one must notify `mysqld' about the new functions with the commands: CREATE FUNCTION metaphon RETURNS STRING SONAME "udf_example.so"; CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so"; CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so"; CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so"; CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so"; Functions should be created only once. The functions can be deleted by: DROP FUNCTION metaphon; DROP FUNCTION myfunc_double; DROP FUNCTION myfunc_int; DROP FUNCTION lookup; DROP FUNCTION reverse_lookup; The `CREATE FUNCTION' and `DROP FUNCTION' update the `func' table. All active function will be reloaded on every restart of server (if -skip-grant-tables is not given). Is *MySQL* picky about reserved words? ====================================== A common problem stems from trying to create a table with column names `timestamp' or `group', the names of datatypes and functions built into *MySQL*. You're allowed to do it (for example, `ABS' is an allowed column name), but whitespace is not allowed between a function name and the `'('' when using the functions whose names are also column names. The following are explictly reserved words in *MySQL*. Most of them (for example) `group', are forbidden by ANSI SQL92 as column and/or table names. A few are because *MySQL* needs them and is (currently) using a yacc parser: `action' `add' `all' `alter' `and' `as' `asc' `auto_increment' `between' `bigint' `bit' `binary' `blob' `both' `by' `cascade' `char' `character' `change' `check' `column' `columns' `create' `data' `database' `databases' `date' `datetime' `day' `day_hour' `day_minute' `day_second' `dayofweek' `dec' `decimal' `default' `delete' `desc' `describe' `distinct' `double' `drop' `escaped' `enclosed' `enum' `explain' `fields' `float' `float4' `float8' `foreign' `from' `for' `full' `grant' `group' `having' `hour' `hour_minute' `hour_second' `ignore' `in' `index' `infile' `insert' `int' `integer' `interval' `int1' `int2' `int3' `int4' `int8' `into' `is' `join' `key' `keys' `leading' `left' `like' `lines' `limit' `lock' `load' `long' `longblob' `longtext' `match' `mediumblob' `mediumtext' `mediumint' `middleint' `minute' `minute_second' `month' `natural' `numeric' `no' `not' `null' `on' `option' `optionally' `or' `order' `outer' `outfile' `partial' `precision' `primary' `procedure' `privileges' `read' `real' `references' `rename' `regexp' `repeat' `replace' `restrict' `rlike' `select' `set' `show' `smallint' `sql_big_tables' `sql_big_selects' `sql_select_limit' `sql_log_off' `straight_join' `starting' `table' `tables' `terminated' `text' `time' `timestamp' `tinyblob' `tinytext' `tinyint' `trailing' `to' `use' `using' `unique' `unlock' `unsigned' `update' `usage' `values' `varchar' `varying' `varbinary' `with' `write' `where' `year' `year_month' `zerofill' The following symbols (from the table above) are disallowed by ANSI SQL but allowed by *MySQL* as column/table names. This is because some of these names are very natural names and a lot of people have already used them. * ACTION * BIT * DATE * ENUM * NO * TEXT * TIME * TIMESTAMP How safe/stable is *MySQL* ************************** How stable is *MySQL*? ====================== At TcX, *MySQL* has worked without any problems in our projects since mid-1996. When released to a wider public we noticed that there were some pieces of 'untested code' in *MySQL* that were quickly found by the new user group who made queries in a different manner. Each new release has had fewer portability problems than the previous one, even though they have all had a lot of new features, and we hope that it will be possible to label one of the next releases 'stable'. Each release of *MySQL* has been usable and there have only been problems when users start to use code from 'the gray zones'. Naturally, outside users can't know what the gray zones are and I hope this section will clarify those currently known. Here we will try to answer some of the more important questions that seems to concern a lot of people and clarify some issues. This section has been put together from the information that has come forward in the mailing list which is very active in reporting bugs. How stable is *MySQL*? Can I depend on *MySQL* in this project? This is about the 3.21.x version of *MySQL*. All known and reported bugs are fixed in the latest version with the exception of the bugs listed in the BUGS file which are things that are 'design' related. *MySQL* is written in multiple layers and different independent modules. Here is a list of the different modules and how tested each of them are. *The ISAM table handler. Stable* This is how all the data is stored. In all *MySQL* releases there hasn't been a single (reported) bug in this code. The only known way to get a corrupted table is to kill the server in the middle of an update and because all data is flushed to disk between each query even this is unlikely to destroy any data beyond rescue. There hasn't been a single bug report about lost data because of bugs in *MySQL* either. *The parser and lexical analyser. Stable* There hasn't been a single reported bug in this system for a couple of months. *The C client code. Stable* No known problems. In early 3.20 releases there were some limitations in the send/receive buffer size. In 3.21.x the send/receive buffer is now dynamic up to a default of 512K. *mysql, mysqladmin and mysqlshow. Stable* The command line clients have had very few bugs. *mysqldump and mysqlimport. Beta* Rewritten for 3.21. *Basic SQL. Stable* The basic SQL function system and string classes and dynamic memory handling. Not a single reported bug on this system. *Query optimiser. Gamma* Some changes in 3.21. *Range optimiser. Alpha* Totally rewritten for 3.21.x *Join optimizer. Gamma* Small changes for 3.21. *GROUP BY, ORDER BY and related function COUNT(). Beta* Rewritten for 3.21 and throughly tested. *Locking. Gamma* This is very system dependent. On some systems there are big problems using standard OS locking (fcntl). In these case one should run the *MySQL* daemon with the `--skip-locking' flag. Known problems are some Linux systems and SunOS when using NFS-mounted file systems. *Linux threads. Gamma* The only problem found is with the fcntl() call, which is fixed by using `--skip-locking'. Some people have reported lockup problems with the 0.5 release. *Solaris 2.5+ pthreads. Stable* We use this for all our production work. *MIT threads (Other systems). Beta* No reported bugs since 3.20.15 and no known bugs since 3.20.16. On some system there is 'misfeature' where some operations are quote slow (a 1/20 second sleep is done between each query). Of course MIT threads may slow down everything a bit, but for index based selects a select is usually done in one time frame so there shouldn't be a mutex locking/thread juggling. *Other thread implementions. Alpha* The ports to other systems are still very new and may have bugs, either in *MySQL* but most often in the thread implementation itself. *LOAD DATA..., INSERT ... SELECT. Stable* Some people have thought they have found bugs in this but have turned up being misunderstandings. So check the manual before reporting bugs! *ALTER TABLE. Gamma* Partly rewritten for 3.21. *mysqlperl. Stable* No bugs reported except a lot of compiling and linking problems. *DBD. Beta* Now maintained by Jochen Wiedmann. <>. Thanks! *mysqlaccess. Beta* Written and maintained by . Thanks! *The Technical Documentation. Beta* It is improving. *MyODBC (uses ODBC SDK 2.5). Beta* It seems to work well with some programs. TcX provides email support for paying customers, but the *MySQL* mailing list usually provides answers to all common questions. Bugs are usually fixed right away with a patch that usually works and for serious bugs there is almost always a new release. Why are there is so many release of *MySQL*? ============================================ Well, *MySQL* is evolving quite rapidly here at TcX and we want to share this with other *MySQL* users. We try to make a release when we have a very useful feature that others seem to have a need for. We also try to help out users who request features that are easy to implement. We also take note on what our licensed users want to have and we especially take notes of what our extended email supported customers want and try to help them out. No one has to download a new release. The News section will tell you if the new release has something you really want. *Note News::. If there is, by any chance, a fatal bug in a release we will make a new release as soon as possible. We would like other companies to do this too. :) The 3.21.x version incorporates major portability changes for many different systems. When the 3.21 release is stable we will remove the alpha/beta suffix and move active development to 3.22. Bugs will still be fixed in the stable version. We don't believe in a complete freeze, as this also leaves out bug fixes and things that 'must be done'. 'Somewhat freezed' means that we will maybe add small things that 'almost surely will not affect anything thats already working'. If you are running and old system and want to upgrade, but you don't want to take chances with 3.21 you should upgrade to 3.20.32. I have tried to only fix fatal bugs and make small, relatively safe changes in this version. If you are trying *MySQL* for the first time or have a little time to test out that your current system, you should use 3.21. Checking a table for errors. ============================ If *MySQL* crashed (for example if the computer is turned off) when all data is not written to disk the tables may have become corrupted. To check a table use: `isamchk table_name' This finds 99.99 % of all errors. What it can't find is when only the data file has been corrupted. `isamchk -e table_name' This goes a complete and through check of all data. It does a check-read of all keys for every row to check that this indeed points to the right row. This may take a LONG time on a big tables with many keys. In normal usage a simple 'isamchk' is safe enough! `isamchk -e -i table_name' As the above but it also prints some statistics. We at TcX run a cron job on all our important tables once a week. 35 0 * * 0 /path/to/isamchk -s /path/to/dbs/*/*.ISM This prints out any crashed tables so we can go and examine and repair them when needed. As we haven't had any unexpected crashes (without hardware trouble) tables for a couple of years now (this is really true), once a week is more than enough for us. Of course, whenever the machine has done a reboot in the middle of a update one usually has to check all the tables that could have been affected. (This is an 'expected crashed table') We recommend that to start with, one should do a `isamchk -s' on all updated tables each night until one comes to trust *MySQL* as much as we do. Naturally, one could add a check to safe_mysql that, if there is an old pid file left after a reboot, it should check all tables that have been modified the last 24 hours. How to repair tables. ===================== The file format that *MySQL* uses to store data has been extensively tested, but there are always instances (like a hard kill on the mysqld process in the middle of a write, a hardware error or a unexpected shutdown of the computer) when some tables may be corrupted. The sign of a corrupted table is usually when queries abort unexpectedly and one gets errors like: * table.frm is locked against change. * Can't find file 'table.ISM' (Errcode: ###) * Got error ### from table handler. (Error 135 is an exception in this case) * Unexpected end of file. * Record file is crashed. In these cases you have to repair your tables. The isamchk external utility can usually detect and fix most things that go wrong. *Note isamchk::. If you are going to use isamchk on very large files, you should first decide how much memory you want to give to isamchk. More memory gives more speed. For example, if you have more than 32M ram, try: isamchk -O sortbuffer=16M -O keybuffer=16M -O readbuffer=1M -O writebuffer=1M .... * Part 1: Checking * Check the permissions of the table files. Make them readable for the user running mysqld. * cd to the database directory. * Run 'isamchk *.ISM' or ('isamchk -e *.ISM' if you have more time). * You only have to repair those tables for which isamchk gives an error. Use option -s to avoid unnecessary information. * Part 2: Easy safe repair. * If you get weird errors when checking or repairing, such as out of memory errors or if isamchk crashes, go to part 3. * Try first 'isamchk -r -q table'. This will try to repair the .ISM file without touching the important data table (.ISD). If the data file (.ISD) contains everything and the delete links point at the right places in the data file, this should work and the table is fixed. Start repairing next table. * Make a backup of the data file (table.ISD) before continuing. * Use 'isamchk -r table'. This will remove wrong records and deleted records from the data file and reconstruct the index (.ISM) file. * If the above fails, use 'isamchk -safe-recover table'. This is a little slower than 'isamchk -recover table' but should work in all cases. * Part 3:; Hard repair. * This should only happen if the first 16K block in the .ISM file is destroyed, contains wrong information or if the .ISM is missing. * In this case we have to create a new .ISM file. Do as follows: * Move the data file .ISD file to some safe place. * Recreate the .ISM file from the .frm file: shell> mysql database mysql> delete from table_name; mysql> quit * Copy (don't move) the data file (.ISD) back on the newly created .ISD file * Go back to Part 2. (This shouldn't be a endless loop). isamchk -r -q should now work. * Part 4: Very hard repair. This can only happen if the descriptor file (.frm) also has crashed. This should never happen, because the .frm file isn't written after the table is created. * Restore the .frm file from a backup and go back to Part 3. You can also restore the .ISM file and go back to Part 2. In the latter case you should start with 'isamchk -r'. * If you don't have a backup but know exactly how the table was created, create a copy of the table in another database and copy the .frm and .ISM file from there to your crashed database and go back to Part 2. Is there anything special to do when upgrading/downgrading *MySQL*? =================================================================== One can always move the *MySQL* form and data files between different versions on the same architecture as long as one has the same base version of *MySQL*. The current base version is of course 3. If one changes the character set (sort order) by recompiling *MySQL* one has to do a `isamchk -r -q' on all tables. If you are paranoid and/or afraid of new versions you can always rename your old mysqld to something like mysqld-'old-version-number'. If your new mysqld then does something unexpected you can simple shut it down and restart with your old mysqld! When you do a upgrade you should of course also take a backup of your old databases. Sometimes its good to be a little paranoid! Upgrading to 3.21 from a 3.20 version ------------------------------------- If you already have a version older than 3.20.28 running and want to switch to 3.21.# you need to do the following: You can start the `mysqld' 3.21 server with `safe_mysqld --old-protocol' to use it with clients from the 3.20 distribution. In this case the new client function, `mysql_errno()', will not return any server error, only `CR_UNKNOWN_ERROR', (but it works for client errors) and the server uses the old password() checking instead of the new one. If you are *NOT* using `--old-protocol': * All client code must be recompiled. If you are using ODBC you must get the new myodbc 2.# driver * The script `scripts/add_long_password' must be run to convert the password field in the 'mysql/user' table to `char(16)'. * All passwords must be reassigned in the mysql/user table (to get 62-bit instead of 31-bit passwords). * The table format hasn't changed so you don't have to convert any tables. *MySQL* 3.20.28 and above can handle the new user table format without affecting clients. If you have a *MySQL* version below 3.20.28, passwords will not work on it anymore if you convert the user table. So to be safe, you should first upgrade to at least 3.20.28 and then upgrade to 3.21.#. The new client code works with a 3.20.# mysqld server, so you can use the old 3.20.# server if you experience problems with 3.21.# without having to recompile the clients again. If you are not using the option `--old-protocol' to `mysqld', old clients will issue the error message: The new perl interface DBI/DBD also supports the old mysqlperl interface. The only change one has to do if one uses mysqlperl is to change the arguments to the connect() function. The new arguments are: host,database,user,password (the user & password arguments has changed places). `ERROR: Protocol mismatch. Server Version = 10 Client Version = 9' Year 2000 compilance ==================== *MySQL* uses Unix times functions and has no problems with dates until 2069; All 2 digit years are regarded to be in the range 1970-2069. In *MySQL* 3.22 the new `YEAR' column type can store years 0, 1901-2155 in 1 byte and display them with 2 or 4 digits. *MySQL* Server functions ************************ Which languages are supported by *MySQL*? ========================================= `mysqld' can give error messages in the following languages: Czech, Dutch, English (default), French, German, Norwegian, Norwegian-ny, Polish, Portuguese, Spanish and Swedish. To start `mysqld' with a language use one of the `--language=lang' or `-L lang' switches: `mysqld --language=swedish' or `mysqld --language=/usr/local/share/swedish' Note that all the language names are in lowercase. The language files are located (by default) in `MYSQL_BASE_DIR/share/LANGUAGE/'. Character set used for data & sorting. -------------------------------------- By default, *MySQL* will use the ISO8859-1 (Latin1) character set. This is the character set used in the USA and western Europe. The character set decides what characters are allowed in names and how things are sorted by the `ORDER BY' and `GROUP BY' commands. You may change this at compile time by the configure switch `--with-charset=charset'. *Note Quick-install::. The Update log ============== When started with the `--log-update=file_name' switch `mysqld' makes a log file with all SQL command that update data. It results in a file with name of `file_name.#' where # is a number that is increased for each refresh. If you do not give a file name the current hostname is used. The logging is smart since it only writes statements that really update data. So an `UPDATE' or a `DELETE' with a `WHERE' that finds no rows is not written to the log. It even skips `UPDATE's that updates a column to the value it had before. If you want to update a database according from a update log you could do the following: cat file-name.* | mysql How big can *MySQL* tables be? ============================== Currently a table is limited to the operation system file size. On Linux the current limit is 2G, on Solaris 2.5.1 the limit is 4G and on Solaris 2.6 the limit is going to be 1000G. To get more that 4G requires some changes to *MySQL* that are on the Todo. *Note Todo::. If your big table is going to be read_only, you could use pack_isam (*Note pack_isam::) to merge and compress many tables to one. As pack_isam usually compresses a table by at least 50%, you can have much bigger tables. Another solution can be the included MERGE library, which allows one to handle a collection of identical tables as one. Currently MERGE can only be used to scan a collection of tables because it doesn't support indexes. We will add indexes to this in the near future. Identical in this case means that all tables are created with identical column information. How to get maximum performance out of *MySQL* ********************************************* How does one change the size of *MySQL* buffers? ================================================ You can get the current buffer sizes with: > `./mysqld --help' This should result in a list of all mysqld options and configurable variables like the following. Possibly variables to option --set-variable (-O) are: back_log current value: 5 join_buffer current value: 131072 key_buffer current value: 1048568 max_allowed_packet current value: 65536 max_connections current value: 90 max_join_size current value: 4294967295 max_sort_length current value: 1024 net_buffer_length current value: 8192 record_buffer current value: 131072 sort_buffer current value: 2097144 table_cache current value: 64 tmp_table_size current value: 1048576 thread_stack current value: 65536 back_log How many outstanding connection requests may *MySQL* have. This comes into play when the main *MySQL* thread gets *VERY* many connection requests in a very short time. It then takes some time (but very short) for the main thread to check the connection and start a new thread. The back_log is how many connects can be stacked during this short time before *MySQL* momentarily stops answering new requests. You only need to increase this if you expect a large number of connections in a short period of time. In other words, the size of the listen queue for incoming tcp/ip connections. The manual page for the unix system call listen(2) should have more details. Check your OS documentation for the maximum value for this variable. join_buffer This buffer is used for full joins (without indexes). It is allocated one time for each full join between two tables. Increase this to get a faster full join when adding indexes is not possible. Normally the best way to get fast joins is by adding indexes. key_buffer Buffers index blocks and are shared by all threads. You might want to increase this when doing many delete/inserts on a table with lots of indexes. To get even more speed use `LOCK TABLES'. *Note Lock tables::. max_allowed_packet Max size of one packet. This allows the message buffer to grow up to this limit when needed (it is initiated to `net_buffer_length'). May be set very big because this is mainly to find erroneous packets. You must increase this if you are using big BLOBS. It should be as big as the biggest BLOB you want to use. max_connections How many simultaneous clients are allowed. If you increase this you probably has to increase the number of file descriptors mysqld has. This is Operating system depended so look at you OS documentation. max_join_size Joins that touch more records than max_join_size return an error. Set this if you have users to tend to make joins without a `WHERE' that take a long time and return millions of rows. max_sort_length The number of bytes to use when sorting on `BLOB' or `TEXT' columns. net_buffer_length The communication buffer is reset to this size between queries. This should not normally be changed, but if you have very little memory you can set it to the expected size of a query. record_buffer Each thread that is doing a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans you may want to increase this. sort_buffer Each thread that needs to do a sort allocates a buffer of this size. Increase this for faster `ORDER BY' or `GROUP BY'. A sort also allocates one or two temporary files. The maximum disk-space needed is `(length_of_what_is_sorted + sizeof(database_pointer)) * number_of_rows * 2'. `sizeof(database_pointer)' is usally 4 but may grow in the future for really big tables. table_cache Number of open tables for all threads. If this is increased you must see to that the number of open file descriptor is also increased. *MySQL* needs two file descriptors for each unique table. tmp_table_size If a temporary table gets bigger than this a `The table ### is full' error will be generated. Increase this if you do many advanced `GROUP BY' queries. thread_stack How big will each threads `C' stack be. A lot of the limits detected by crash-me are dependent on this. The default is normally enough. *MySQL* uses algorithms that are very scalable so one can usually run with very little memory or give *MySQL* more memory to get better performance. If you have much memory and many tables and want maximum performance with a moderate number of clients you should use something like: > safe_mysqld -O key_buffer=16M -O table_cache=128 \ -O sort_buffer=4M -O record_buffer=1M & If you have little memory with lots of connections, use something like: > safe_mysqld -O key_buffer=512k -O sort_buffer=100k -O record_buffer=100k & or even > safe_mysqld -O key_buffer=512k -O sort_buffer=16k -O table_cache=32 \ -O record_buffer=8k -O net_buffer=1K & Note that if you change an option to `mysqld' it is only for that instance of the server. To see the effects of a parameter change, do something like this `mysqld -O key_buffer=32m --help'. You can check the parameters in effect with `mysqladmin variables'. If there are very many connections, 'swapping problems' may occur if mysqld has not been configured to use very little memory for each connection. It also works better if you have a enough memory for all connections of course. For example, for 200 open connections one should have a table cache of at least 200 * (max_number of tables in join). How compiling and linking affects the speed of *MySQL* ====================================================== Most of the following test are done on Linux and with the *MySQL* benchmarks, but they should give some indication for other operating systems: On Linux you will get the fastest code when compiling with pgcc and -O6. To compile sql_yacc.cc with these options one needs 180M memory as gcc/pgcc needs a lot of memory to make all functions inline. The fastest code is when you link with -static and use Unix socket to connect to the database. bullet If you use pgcc instead of gcc and compile everything with -O6 the program will be 11 % faster. bullet If you link dynamicly (without -static), the result is 13 % slower. bullet If you use TCP/IP instead of Unix sockets (connection to localhost), the result is 7.5 % slower. bullet On a Sun sparcstation 10 gcc 2.7.3 is 13 % faster than Sun Pro C++ 4.2. bullet On Solaris 2.5.1 mit-pthreads is 8-12% slower than Solaris native threads. The MySQL-linux distribution that is distributed by TCX is compiled with pgcc and linked staticly. How does *MySQL* use memory ? ============================= * The key_buffer is shared by all threads, the rest are allocated when needed. * Each connection uses some thread space, a stack (64K) and a connection buffer (variable `net_buffer_length'). * All threads share the same base memory. * Nothing is memmapped yet (except compressed tables but that's another story). This is because the 32-bit memory space of 4GB is not large enough for most large tables. When we get a system with 64-bit address space we may add general support for memmaping. * When starting `mysqld' one can specify a key buffer. This will buffer all indexes in all tables on a FIFO basis (variable key_buffer). * Each request doing a sequential scan over a table allocates a read buffer (variable record_buffer). * Each request doing a sort allocates a sortbuffer and one or two temporary files. The maximum extra disk-space needed is (sort_key_length +sizeof(long))*2. * All joins are done in one pass and most joins can be done without even using a temporary table. Most temporary tables are memory based (HEAP) tables. Temporary tables with a big recordlength (= sum of all column lengths) or that contains `BLOB's are stored on disk. One current problem is that if the HEAP table exceeds the size of `tmp_table_size', one will get the error: 'The table ### is full'. In the future we will fix this by automatically changing the in memory (HEAP) table to a disk based (NISAM) table if needed. To go around this problem one can increase the `-O tmp_table_size=#' option to mysqld or use the SQL option `SQL_BIG_TABLES'. *Note Set option::. In *MySQL* `3.20' the maximum size of the temporary table was `recordbuffer*16', so if you are using this version you have to increase `recordbuffer'. There also exists a patch to always store temporary tables on disk, but this will affect the speed of all complicated queries. * Almost all memory used when parsing and calculating is done in a local memory store. No memory overhead is needed for small items and the normal slow memory allocation/freeing is avoided. Memory is only allocated for unexpectedly large strings (this is done with malloc/free). * Each index file is opened once and the data file is opened once for each concurrently-running thread. For each concurrent thread a table structure, column structures for each column, and a buffer that has the size of 3 * (maximum row length not counting `BLOB's) is allocated. A `BLOB' uses 5 to 8 bytes +length of blob data. * For each table having `BLOB's, a buffer is enlarged dynamically to read in larger `BLOB's. If one scans a table there will be a allocated buffer as large as the largest `BLOB'. * All used tables are saved in a cache and managed as a FIFO. Normally the cache is 64 tables. If a table has been used by two running threads at the same time, there will be two entries of the table in the cache. * A `mysqladmin refresh' closes all tables that are not in use and marks all used tables to be closed when the running thread finishes. This will effectively free most used memory. All log files are also closed and reopened. When running *mysqld* `ps' and other programs may report that it uses a lot of memory. This may be caused by thread-stacks on different memory addresses. For example, the Solaris ps calculates the unused memory between stacks as used memory. You can verify this by checking available swap with 'swap -s'. We have tested `mysqld' with commercial memory-leakage detectors so there should not be any memory leaks. How does *MySQL* use indexes? ============================= All indexes, `PRIMARY', `UNIQUE' and `INDEX()', are stored in B trees. Strings are automatically prefix- and end-space compressed. `INDEX(col1, col2)' creates a multiple index over the two columns. The index can be seen as a concatenation of the given columns. If you use `INDEX(col1)', `INDEX(col2)' instead of `INDEX(col1,col2)' you get two separate indexes instead. SELECT * FROM table WHERE col1=# AND col2=# In a case of `INDEX(col1,col2)' the right row(s) can be fetched directly. In a case of `INDEX(col1)', `INDEX(col2)' the optimiser decides which index will find fewer rows and this index will be used to fetch the rows. If the table has an index `INDEX(col1,col2,col3...)' the prefix of this can be used by the optimiser to find the rows. This means that the above gives you search capabilities on: `INDEX(col1)' and `INDEX(col1,col2)' and `INDEX(col1,col2,col3)'... MySQL can't use a portion of an index to locate rows through an index. With the definition `INDEX(col1,col2,col3)': SELECT * FROM table WHERE col1=# SELECT * FROM table WHERE col2=# SELECT * FROM table WHERE col2=# and col3=# only the first query will use indexes. *MySQL* will also use indexes if the `LIKE' argument is a constant string that doesn't start with a wild character: The following will use indexes: SELECT * from table WHERE key_column like "Patrick%"; SELECT * from table WHERE key_column like "Pat%_ck%"; In the above cases only rows with `Patrick <= key_column < Patricl' and `Pat <= key_column < Pau' will be considered. The following selects will not use indexes: SELECT * from table WHERE key_column like "%Patrick%"; SELECT * from table WHERE key_column like other_column; What kind of optimisation is done on the WHERE clause? ====================================================== (Incomplete, *MySQL* does a lot of optimisations.) The first issue about making a slow `SELECT ... WHERE' faster is to check if one could add an index. All references between different tables should usually be done with indexes. One can use the `EXPLAIN' command to check which indexes are used in a `select'. *Note Explain::. *Note MySQL indexes:: * Brace removal (all unnecessary braces are removed). `((a AND b) AND c OR (((a AND b) AND (c AND d))))' -> `(a AND b) OR (a AND b AND c AND d)' * Constant folding. `(a `b>5 AND b=c AND a=5' * Constant condition removal (needed because of constant folding). `(b>=5 AND b=5) OR (b=6 AND 5=5) OR (B=7 AND 5=6)' -> `B=5 OR B=6' * All constant expressions used by indexes are evaluated only once. * `CONST(*)' on a single table without a `WHERE' is retrieved directly from the table. This is also done for any `NOT NULL' expression under the same conditions. * Early detection of invalid constant expressions. Return zero rows if impossible select. * `HAVING' is merged with `WHERE' if one doesn't use `GROUP BY' or group functions. * For each sub join a simpler `WHERE' is constructed to get a fast `WHERE' evaluation for each sub join and also to skip records as soon as possible. * Find all indexes that may be used. Use the index which finds least records. An index is used for the following cases: `=', `>', `>=', `<', `<=', `BETWEEN' and a `LIKE' with a character prefix like 'something%'. * Remove indexes that don't span all `AND' levels. - have all preceding index_parts specified. - `index = 1 or A = 10' -> `NULL' (can't use index.) - `index = 1 or A = 10 and index=2' -> `index = 1 OR index = 2' - `index_part_1 = const and index_part_3 = const' -> `index_part_1 = const' * Read all constant tables. A constant table is: 1. A table with 0 or 1 record. 2. A table which uses only other const tables and constants on a full unique index. `const_table.index = constant' * `const_table.index_part_1 = const_table2.column and const_table.index_part_2 = constant' * Find the best join combination to join the tables, by trying all possibilities :(. If all columns in `ORDER BY' and in `GROUP' come from the same table, then this table is preferred first when joining. * If there is an order clause and a different group clause, or if the order or group contains columns from other tables than the first table in the join queue, a temporary table is created. * For each table use a ranged index, if possible, to read records. Each table index is queried and if there is an index range that spans < 30% of the records then an index is used. If no such index can be found a quick table scan is used. * Before each record is output, skip those that match the `HAVING' clause. How does *MySQL* open & close tables? ===================================== The cache of open tables can grow to a maximum of `table-cache' (default 64, changeable with -O table_cache=#). A table is never closed, except when the cache is full and another thread tries to open a table or if one uses 'mysqladmin refresh'. When the limit is reached, *MySQL* closes as many tables as possible, until the cache size has been reached or there are no more unused tables. This means that if all tables are in use by some threads, there will be more open tables than the cache limit, but the extra tables will be closed eventually. Tables are closed according to last-used order. A table is opened (again) for each concurrent access. This means that if one has two threads running on the same table or access the table twice in the same query (with `AS') the table needs to be opened twice. The first open of any table takes two file descriptors, each following use of the table takes only one file descriptor. If *MySQL* notices that a table is a symbolic linked it will resolve the symlink and use the table it points to instead. This works on all system that supports the realpath() call (At least Linux and Solaris supports realpath()! On system that doesn't supports realpath() you should not use the symlink and the table at the same time! The tables will be inconsistent after any update to the tables. *MySQL* doesn't support linking of databases by default. Things will work fine as long as you don't make a symbolic link between databases. The following shows a case that *DOES NOT* work: db2->db1 db1/ If you really need this you have to change in mysys/mf_format.c: if (!lstat(to,&stat_buff)) /* Check if it's a symbolic link */ if (S_ISLNK(stat_buff.st_mode) && realpath(to,buff)) to if (realpath(to,buff)) What are the drawbacks of creating possibly thousands of tables in a database? .............................................................................. Each table is actually three files. If you have many files in a directory open, close and create will be slow. If you also do selects on many different tables there will be a little overhead because when the table cache is full, for every table that has to be opened another has to be closed. One can make the overhead smaller by making the table cache larger. How does *MySQL* lock tables? ============================= All locking in MySQL is deadlock free. This is managed by always requesting all needed locks at once at query start and always locking the tables in the same order. The locking method *MySQL* uses for `WRITE' lock works as follows: If there is no locks on the table, put a write lock on it, else put the lock in the write lock queue. The locking method *MySQL* uses for `READ' locks works as follows: If there is no write locks on the table, put a read lock on it else put the lock in the read lock queue. When a lock is released first use give the lock to the threads in the write lock queue and after this to the threads in the read lock queue. This means that if you have many updates on the same table, select statements will be waiting until there is no more updates. To fix this in the case where you do many inserts and many selects on the same table you could insert rows in another table and once in a while update the other table with all records from the temporary table. This can be done with the following code: LOCK TABLES real_table WRITE, insert_table WRITE insert into real_table select * from insert_table delete from insert_table UNLOCK TABLES One could also change the locking code in mysys/thr_lock.c to use only one queue. In this case write locks would have the same priority that read locks and this could help some applications. How should I arrange my table to be as fast/small as possible? ============================================================== * Use `NOT NULL' if possible. It makes everything faster and you save one bit per column. * All columns have default values. Only insert when the default value isn't acceptable. You don't have to insert the columns of a timestamp or an autoincremented index in the insert statement. *Note mysql_insert_id::. * Use the smaller INT types if possible to get smaller tables. For example, `MEDIUMINT' is often better than `INT'. * If you don't have any `VARCHAR' columns, a fixed size record format will be used. This is much faster but may unfortunately waste some space. *Note Row format::. * To make *MySQL* optimize queries better, run `isamchk --analyze' on the table once it is loaded with relevant data. This updates a value for each index that tells how many rows that have the same value for this index on average. Of course, this is always 1 for unique indexes. * To sort an index and data according to an index use `isamchk --sort-index --sort-records=1' (if you want to sort on index 1). If you have a unique index from which you want to read all records in numeric order, this is a good way to make that faster. * When loading a table with data use `LOAD DATA FROM INFILE'. This is usually 20 times faster than using a lot of `INSERT's. If the text file isn't on the server, rcp it to the server first. *Note Load::. You can even get more speed when loading data to tables with many indexes by doing: * Create the table in mysql or perl with `CREATE TABLE...' * Do `mysqladmin refresh'. * Use `isamchk --keys-used=0 database/table_name'. This will remove all usage of all indexes from the table. * Insert data into the table with `LOAD DATA INFILE...'. * If you have pack_isam and want to compress the table, run pack_isam on it. * Recreate the indexes with `isamchk -r -q database/table_name'. * Do `mysqladmin refresh'. The other possibility to get some more speed for both `LOAD DATA FROM INFILE' and `INSERT' is to enlarge the key buffer. This can be done with the `-O key_buffer=#' option to `(safe)mysqld'. For example 16M should be a good value if you have much RAM :) * When dumping data as textfiles to other programs, use `SELECT ... INTO OUTFILE'. *Note Load::. * When doing many inserts/updates in a row, you can get more speed by using `LOCK TABLES' on the tables. `...FROM INFILE...' and `...INTO OUTFILE...' are atomic so you don't have to use `LOCK TABLES' when using these. *Note Lock tables::. To check how you are doing, run `isamchk -evi' on the .ISM file. What affects the speed of the INSERT statement? =============================================== The time to insert a record consists of: * Connect: (3) * Sending query to server: (2) * Parsing query: (2) * Inserting record: (1 x size of record) * Inserting indexes: (1 x indexes) * Close: (1) Where (number) is proportional time. This does not take into consideration the initial overhead to open tables (which is done once for each simultaneous running query). The size of the table slows down the insert of indexes by N log N (B-trees). A way of speeding up inserts is to lock your table during the inserts. LOCK TABLES a WRITE; INSERT INTO a VALUES (1,23) INSERT INTO a VALUES (2,34) INSERT INTO a VALUES (4,33) INSERT INTO a VALUES (8,26) INSERT INTO a VALUES (6,29) UNLOCK TABLES; The main speed difference is that the index buffer is only flushed once to disk for all inserts. Normally there would be as many index buffer flushes as there are inserts. Locking will also lower the total time of multi-connection test but the maximum wait time for some threads will go up. For example: thread 1 does 1000 inserts thread 2, 3, and 4 does 1 insert thread 5 does 1000 inserts If you don't use locking, 2, 3 and 4 will finish before 1 and 5. If you use locking 2,3,4 may finish before 1 or 5 but probably not, but the total time should be about 40% faster. As `INSERT's, `UPDATE's and `DELETE's are very fast in *MySQL*, one will obtain better overall performance by adding locks around everything that does more than about 5 inserts/updates in a row. If one does very many inserts in a row one could do a `UNLOCK TABLES' followed by a `LOCK TABLES' once in a while (about each 1000 rows) to give other threads access to the table. This would still give a nice performance gain. Of course `LOAD DATA INFILE' is much faster still. What affects the speed of DELETE statement? =========================================== The delete time of a record is exactly proportional to the number of indexes. To increase the speed of deletes you can increase the size of the index cache. The default index cache is 1M and to get faster deletes it should be increased by several factors (try 16M if you have enough memory). How do I get *MySQL* to run at full speed? ========================================== * Start `mysqld' with the right options. More memory gives more speed if you have it. *Note MySQL parameters::. * Create indexes to make your `SELECT's faster. *Note MySQL indexes:: * Optimize your column types to be as efficient as possible. Use `NOT NULL' on all columns. *Note Table efficiency:: * `--skip-locking' disables file locking between SQL requests. This gives a greater speed but has the following consequences: * One *MUST* flush all tables with `mysqladmin refresh' before one tries to check/repair tables with `isamchk'. (`isamchk -d table_name' is always allowed). * One can't run two *MySQL* servers one the same data files, if both are going to update the same tables. The `--skip-locking' is on by default when compiling with MIT threads. This is because flock() isn't fully supported by MIT threads on all platforms. * If updates are a problem, one can delay updates and then do many updates in a row later. Many updates done in a row are much quicker than one at a time. * If the problem is with MIT threads and one is using FreeBSD, upgrading to FreeBSD 3.0 (or higher) should help. This gives a possibility to use sockets (quicker than the current TCP/IP with MIT threads) and the thread package is much more integrated. What are the different row formats? Or when to use VARCHAR/CHAR? ================================================================ MySQL dosen't have true SQL VARCHAR() types. MySQL has instead 3 different ways to store records and uses this to emulate `VARCHAR()': If one doesn't use any of the `VARCHAR', `BLOB' or `TEXT' column types a fixed row size is used, otherwise a dynamic row size is used. `CHAR()' and `VARCHAR()' are treated identically from the applications point of view; Both truncates end space from the column when the column is accessed. You can check the format used in a table with `isamchk -d'. *MySQL* has three different table formats: 1. Fixed length tables. * This is the default format. It's used when there is no VARCHAR(), TEXT or BLOB column types in the table. * All CHAR(), NUMERIC() and DECIMAL() columns are space filled. * Very quick. * Easy to cache. * Easy to reconstruct after a crash as records are in fixed positions. * Don't have to be reorganised (with isamchk) unless a huge number of records are deleted and one wants to free space to the operating system. * This will usually take more disk space than dynamic tables. 2. Dynamic tables * Is used if there exists any columns with a `VARCHAR', `TEXT' or `BLOB' type in a table. * All strings are dynamic (except if length < 3). * Each record is preceded with a bitmap for which columns are empty (") or zero (this isn't the same as null columns). Each string is saved with a length byte + string. If string is zero length or is number zero it is marked in the bit map and not saved to disk. * Each record is uses the exact record space required. If a record becomes larger it is split into as many pieces as required. * Takes usually much less disk space than fixed length records. * If one updates rows with information that extends the row length the row will be fragmented. In this case one may have to run `isamchk -r' from time to time to get better performance. Use `isamchk -ei table_name' for some statistics. * Not as easy to reconstruct because a record may be in many pieces and a link may be missing. * The expected row length for dynamic sized records is: 3 + (number_of_columns + 7) / 8 + (number of char columns) + packed_size_of_number_columns + length_of_strings + (null_columns + 7) / 8. There will be a penalty of 6 bytes for each link. A dynamic record will be linked whenever an update causes an enlargement of the record. Each new link will be at least 20 bytes, so the next enlargement will probably go in the same link. If not, there will be another link. You may check how many links there are with `isamchk -ed'. All links may be removed with `isamchk -r'. 3. Compressed tables: * A read only table made with the pack_isam utility. All customers with extended *MySQL* email support are entitled to a copy of pack_isam for their intern usage. * The uncompress code exists in all MySQL distributions so even customers that doesn't have pack_isam can read tables compressed with pack_isam (on the same platform). * Takes very little disk space. Minimises disk usage. * Each record is compressed separately (very little access overhead). The header for a record is fixed 1-3 bytes depending on the biggest record in the table. Each column is compressed differently. Some of the compression types are: * There is usually a different Huffman table for each column. * Suffix space compression. * Prefix space compression. * Numbers with value 0 is stored with 1 bit. * If a integer is used with a smaller range the integer column is stored with the smallest possibly type. For example a LONGLONG (8 bytes) column may be stored as TINYINT column if all values are in the range 0-255. * If a value has only a small set of possible values, the value is converted to enum(). * A column may use a combination of the above compressions. * Can handle fixed or dynamic length records, but no BLOB or TEXT columns. * Can be uncompressed with isamchk. MySQL can support different index types, but the normal one is NISAM. This is a B-tree index and one can roughly calculate the size for the index file as: sum over all keys: `(key_length+4)*0.67' (This is for the worst case when all keys are inserted in sorted order. String index are space compressed and if the first index part is a string it will also be prefix compressed. This will usually make the index file smaller if the columns are not filled up to 100% or if there are many duplicates. Why so many open tables? ======================== When you run `mysqladmin status' you get something like: Uptime: 426 Running threads: 1 Questions: 11082 Reloads: 1 Open tables: 12 This can be somewhat perplexing if you only have 6 tables. As *MySQL* is multithreaded it may have many queries on the same table at once. To minimise the problem with two threads having different states on the same file, I open the table again for each concurrent thread. This takes some memory and one extra file descriptor for the data file. The index file descriptor is shared between all threads. *MySQL* benchmark suite *********************** This should contain a technical description of the *MySQL* benchmark suite (and crash-me) but that description is not written yet. Currently see the code and results in the `bench' directory in the distribution. And of course on the web page (http://www.tcx.se/crash-me.html). It is meant to be a benchmark that will tell any user what things a given SQL implementation is good or bad at. crash-me tries to find what a database supports by actually running queries. It find for example: * What column types are supported. * How many indexes. * What functions are supported. * How big can a query be. * How big can a varchar column be. *MySQL* Utilites **************** Overview of the different *MySQL* programs ========================================== All *MySQL* clients that communicate with the server using the `mysqlclient' library use the following environment variables: Name Description MYSQL_UNIX_PORT The default socket. Used with 'localhost'. MYSQL_TCP_PORT The default TCP port. MYSQL_PWD The default password. MYSQL_DEBUG Debug-trace options when debugging. TMPDIR Directory where temporary tables/files are created. All MySQL programs take many different options. Use the switch -help to get a full description of the different options. Try for example `mysql --help'. `mysql' mysql is a simple SQL shell (with gnu readline). It supports interactive use and non-interactive querying. When used interactively, the result are given in an ascii-table format, but when used as a filter the result is a tab-separated output (this as other things can be changed with startup options). You can simply run scripts with `mysql database < script.sql > output.tab'. If you have a problem with that the memory in the client is not enough, use the `--quick' switch! This will force mysql to use `mysql_use_result()' instead of `mysql_store_result()' to retrieve the result set. `mysqlaccess' Script to check the privileges for a host, user and database combination. `mysqladmin' Administration utility. Create/Drop databases, reload (read new users) and refresh (flush tables to disk, reopen log files). Also gives version, process and status information from the server. `mysqld' The SQL daemon. This should always be running. `mysqldump' Dump a *MySQL* database into a file with SQL statements or tab separated text files. Enhanced freeware originally by Igor Romanenko. `mysqlimport' Imports one or more text files into respective tables. Can use all formats supported by `LOAD DATA INFILE'. *Note Load:: `mysqlshow' Shows information about databases, tables, columns and indexes. `mysqlbug' This script should always be used when filing a bug report to the *MySQL* list. `mysql_install_db' Creates the *MySQL* grant tables with default privileges. This is usually only executed once when installing the first *MySQL* release on a new system. `isamchk' Check, optimise and repair *MySQL* tables. `make_binary_release' Makes a binary release of a compiled *MySQL*. This could be sent by ftp to /pub/mysql/Incoming on www.tcx.se for the convenience of other *MySQL* users. `msql2mysql' A shell script to convert a `mSQL' program to *MySQL*. Doesn't handle all cases but gives a good start when converting. `replace' Binary used for msql2mysql. Utility program to change strings in place in files or on stdin. Uses a finite state machine to match longer strings first. Can be used to swap strings, for example `replace a b b a -- files' swaps `a' and `b' in the given files. `safe_mysqld' Starts the mysqld daemon with some safety features. Restarts on error and has logging of runtime information to a log file. The *MySQL* table check, optimise and repair program ==================================================== You can get all options for isamchk with `isamchk --help'. For information about how to use isamchk to repair a crashed table: *Note Repair::. isamchk memory use ------------------ `isamchk' doesn't use any more memory than you define with the `-O' options. The default is to use only about 2M to fix things. By using bigger values you can get isamchk to operate faster. Using `-O sortbuffer=16M' should probably be enough for most cases. But `isamchk' uses temporary files in `TMPDIR'. If `TMPDIR' points to a memory file system you may easily get out of memory errors. Getting low level table information ----------------------------------- To get a description/statistics from a table use the methods below. We will explain some of the information in more detail later. `isamchk -d table_name' isamchk in 'describe mode'. If one uses `--skip-locking' `isamchk' may report an error for a table that is updated while isamchk runs, but there isn't any risk of destroying data. `isamchk -d -v table_name' A little more verbose. `isamchk -eis table_name' Shows only the most important information from a table. It is slow since it must read the whole table. `isamchk -eiv table_name' Same as above but tells you what it is being done. Example of `isamchk -d' output: ISAM file: company.ISM Data records: 1403698 Deleted blocks: 0 Recordlength: 226 Record format: Fixed length table description: Key Start Len Index Type 1 2 8 unique double 2 15 10 multip. text packed stripped 3 219 8 multip. double 4 63 10 multip. text packed stripped 5 167 2 multip. unsigned short 6 177 4 multip. unsigned long 7 155 4 multip. text 8 138 4 multip. unsigned long 9 177 4 multip. unsigned long 193 1 text Example of `isamchk -d -v' output: ISAM file: company.ISM Isam-version: 2 Creation time: 1996-08-28 11:44:22 Recover time: 1997-01-12 18:35:29 Data records: 1403698 Deleted blocks: 0 Datafile: Parts: 1403698 Deleted data: 0 Datafilepointer (bytes): 3 Keyfile pointer (bytes): 3 Max datafile length: 3791650815 Max keyfile length: 4294967294 Recordlength: 226 Record format: Fixed length r table description: Key Start Len Index Type Root Blocksize Rec/key 1 2 8 unique double 15845376 1024 1 2 15 10 multip. text packed stripped 25062400 1024 2 3 219 8 multip. double 40907776 1024 73 4 63 10 multip. text packed stripped 48097280 1024 5 5 167 2 multip. unsigned short 55200768 1024 4840 6 177 4 multip. unsigned long 65145856 1024 1346 7 155 4 multip. text 75090944 1024 4995 8 138 4 multip. unsigned long 85036032 1024 87 9 177 4 multip. unsigned long 96481280 1024 178 193 1 text Example of `isamchk -eis' output: Checking ISAM file: company.ISM Key: 1: Keyblocks used: 97% Packed: 0% Max levels: 4 Key: 2: Keyblocks used: 98% Packed: 50% Max levels: 4 Key: 3: Keyblocks used: 97% Packed: 0% Max levels: 4 Key: 4: Keyblocks used: 99% Packed: 60% Max levels: 3 Key: 5: Keyblocks used: 99% Packed: 0% Max levels: 3 Key: 6: Keyblocks used: 99% Packed: 0% Max levels: 3 Key: 7: Keyblocks used: 99% Packed: 0% Max levels: 3 Key: 8: Keyblocks used: 99% Packed: 0% Max levels: 3 Key: 9: Keyblocks used: 98% Packed: 0% Max levels: 4 Total: Keyblocks used: 98% Packed: 17% Records: 1403698 M.recordlength: 226 Packed: 0% Recordspace used: 100% Empty space: 0% Blocks/Record: 1.00 Recordblocks: 1403698 Deleteblocks: 0 Recorddata: 317235748 Deleted data: 0 Lost space: 0 Linkdata: 0 User time 1626.51, System time 232.36 Maximum resident set size 0, Integral resident set size 0 Non physical pagefaults 0, Physical pagefaults 627, Swaps 0 Blocks in 0 out 0, Messages in 0 out 0, Signals 0 Voluntary contexts switches 639, Involuntary contexts switches 28966 Example of `isamchk -eiv' output: Checking ISAM file: company.ISM Data records: 1403698 Deleted blocks: 0 - check file-size - check delete-chain index 1: index 2: index 3: index 4: index 5: index 6: index 7: index 8: index 9: No recordlinks - check index reference - check data record references index: 1 Key: 1: Keyblocks used: 97% Packed: 0% Max levels: 4 - check data record references index: 2 Key: 2: Keyblocks used: 98% Packed: 50% Max levels: 4 - check data record references index: 3 Key: 3: Keyblocks used: 97% Packed: 0% Max levels: 4 - check data record references index: 4 Key: 4: Keyblocks used: 99% Packed: 60% Max levels: 3 - check data record references index: 5 Key: 5: Keyblocks used: 99% Packed: 0% Max levels: 3 - check data record references index: 6 Key: 6: Keyblocks used: 99% Packed: 0% Max levels: 3 - check data record references index: 7 Key: 7: Keyblocks used: 99% Packed: 0% Max levels: 3 - check data record references index: 8 Key: 8: Keyblocks used: 99% Packed: 0% Max levels: 3 - check data record references index: 9 Key: 9: Keyblocks used: 98% Packed: 0% Max levels: 4 Total: Keyblocks used: 9% Packed: 17% - check records and index references [LOTS OF ROW NUMBERS DELETED] Records: 1403698 M.recordlength: 226 Packed: 0% Recordspace used: 100% Empty space: 0% Blocks/Record: 1.00 Recordblocks: 1403698 Deleteblocks: 0 Recorddata: 317235748 Deleted data: 0 Lost space: 0 Linkdata: 0 User time 1639.63, System time 251.61 Maximum resident set size 0, Integral resident set size 0 Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0 Blocks in 4 out 0, Messages in 0 out 0, Signals 0 Voluntary contexts switches 10604, Involuntary contexts switches 122798 Here are the data file sizes of the table used above. -rw-rw-r-- 1 monty tcx 317235748 Jan 12 17:30 company.ISD -rw-rw-r-- 1 davida tcx 96482304 Jan 12 18:35 company.ISM Explanations for the things `isamchk' prints: `ISAM file' Name of isam file. `Isam-version' Version of isam format. Currently always 2. `Creation time' When was the data file created. `Recover time' When was the index/data file last reconstructed. `Data records' How many records/rows. `Deleted blocks' How many deleted blocks still have reserved space. *Note Repair::. `Datafile: Parts' For dynamic record format this shows how many data blocks there are. For an optimised table without splits this is the same as `Data records'. `Deleted data' How many bytes of non-reclaimed deleted data. `Datafile pointer' Size (in bytes) of the datafile pointer. It is usually 2, 3, 4 or 5 bytes. Most tables manage with 2 bytes but this cannot be controlled from *MySQL* yet. For fixed tables this is a record address. For dynamic tables this is a byte address. `Keyfile pointer' How many bytes has the datafile pointer. It is usually 1, 2 or 3 bytes. Most tables manage with 2 bytes but this is calculated automatically by *MySQL*. It is always a block address. `Max datafile length' How long (in bytes) can the table's data file (`.ISD') get. `Max keyfile length' How long (in bytes) can the table's key file (`.ISM') get. `Recordlength' How much space does each record/row take. `Record format' Which format does each record/row have. This example uses `Fixed length'. `table description' A list of all keys in the table. For each key some low level information is presented. `Key' This key's number. `Start' Where in the record/row does this index-part start. `Len' How long is this index part. For packed numbers this should always be the full length of the column. For strings it may be shorter than the full length. `Index' `unique' or `multip.'. If one value can exist multiple times in this index. `Type' What data-type does this index part have. This is a `C' data-type with the options packed, stripped or empty. `Root' Address of the root index block. `Blocksize' The size of each index block. This is by default 1024 but may be changed at compile time. `Rec/key' This is a statistical value used by the optimiser. It tells how many records there are per value for this key. A unique key always has a value of 1. This may be updated after a table is loaded (or greatly changed) with `isamchk -a'. If this is not updated at all, a default value of 30 is given. `' The 9th key is a multi-part key with two parts. `Keyblocks used' What percentage of the keyblocks are used. Since this table has just been reorganised with isamchk the values are very high (very near theoretical maximum). `Packed' MySQL tries to pack keys with a common suffix. This can only be used for `CHAR'/`VARCHAR'/`DECIMAL' keys. For long strings like names, this can significantly reduce the space used. In the above example the 4th key is 10 characters long and gets a 60% reduction in space. `Max levels' How deep is the btree for this key. Large tables with long keys get high values. `Records' How many rows does the table have. `M.recordlength' Average recordlength. For fixed tables this is the recordlength. `Packed' *MySQL* strips spaces from the end of strings. What percentage did we save by doing this. `Recordspace used' What percentage of the datafile is used. `Empty space' What percentage of the datafile is unused. `Blocks/Record' How many blocks are there per record. This is always 1 for fixed format tables. This value should stay as close to 1.0 as possible. If it gets too big you can reorganise the table with `isamchk'. *Note Repair::. `Recordblocks' How many blocks are used. For fixed format, this is the same as the number of records. `Deleteblocks' How many blocks are deleted. `Recorddata' How many bytes of actual user data there are in the datafile. `Deleted data' How many bytes of deleted data there are in the datafile. `Lost space' If a record is updated to a shorter length, some space is lost. This is the sum of all such losses. `Linkdata' When the dynamic format is used, blocks are linked with pointers (length 4-7 bytes). This is the sum of all such pointers. The *MySQL* compressed read only table generator ================================================ `pack_isam' is an extra that you get when ordering more than 10 licenses or extended support. Since `pack_isam' is distributed binary only, `pack_isam' is only available on some platforms. Of course, all future updates to `pack_isam' is included in the price. `pack_isam' may at some time be included as standard when we get some kind of turnover for *MySQL*. `pack_isam' works by compressing each column in the table separately. The information needed to decompress is read into memory when the table is opened. This gives a much better performance when accessing individual records as one only has to uncompress exactly one record, not a much larger disk block like when using Stacker on MSDOS. MySQL uses memory mapping (mmap) on compressed tables and falls back to normal read/write file usage if mmap doesn't work. Usually, `pack_isam' packs the datafile 40-70%. There is currently two limitations with `pack_isam': After packing, the table is read only. * It can't pack blobs, yet. Fixing these limitations is on our TODO but with low priority. `pack_isam' options: > pack_isam --help pack_isam Ver 5.0 for SOLARIS 2.5 on SPARCstation Copyright (C) 1994-1997 TcX AB & Monty Program KB & Detron HB. This is not free software. You must have a license to use this program This software comes with ABSOLUTELY NO WARRANTY Pack an ISAM-database to take much smaller space Keys are not updated, one must run isamchk -rq on datafile afterwards Usage: pack_isam [OPTIONS] -b, --backup Make a backup of the table as table_name.OLD -f, --force Force packing of table even if it's gets bigger or tempfile exists. -j, --join=# Join all given tables into table. All tables MUST be identical. -p, --packlength=# Force storage size of recordlength (1,2 or 3) -s, --silent Be more silent. -t, --test Don't pack table only test packing it -v, --verbose Write info about progress and packing result -w, --wait Wait and retry if table is in use -T, --tmp_dir=# Use temporary directory to store temporary table -#, --debug=... output debug log. Often this is 'd:t:o,filename` -?, --help display this help and exit -V, --version output version information and exit Typical run: (/my/monty/tmp) ls -l station.* -rw-rw-r-- 1 monty my 994128 Apr 17 19:00 station.ISD -rw-rw-r-- 1 monty my 53248 Apr 17 19:00 station.ISM -rw-rw-r-- 1 monty my 5767 Apr 17 19:00 station.frm (/my/monty/tmp) isamchk -dvv station ISAM file: station Isam-version: 2 Creation time: 1996-03-13 10:08:58 Recover time: 1997-02-02 3:06:43 Data records: 1192 Deleted blocks: 0 Datafile: Parts: 1192 Deleted data: 0 Datafilepointer (bytes): 2 Keyfile pointer (bytes): 2 Max datafile length: 54657023 Max keyfile length: 33554431 Recordlength: 834 Record format: Fixed length table description: Key Start Len Index Type Root Blocksize Rec/key 1 2 4 unique unsigned long 1024 1024 1 2 32 30 multip. text 10240 1024 1 column Start Length Type 1 1 1 2 2 4 3 6 4 4 10 1 5 11 20 6 31 1 7 32 30 8 62 35 9 97 35 10 132 35 11 167 4 12 171 16 13 187 35 14 222 4 15 226 16 16 242 20 17 262 20 18 282 20 19 302 30 20 332 4 21 336 4 22 340 1 23 341 8 24 349 8 25 357 8 26 365 2 27 367 2 28 369 4 29 373 4 30 377 1 31 378 2 32 380 8 33 388 4 34 392 4 35 396 4 36 400 4 37 404 1 38 405 4 39 409 4 40 413 4 41 417 4 42 421 4 43 425 4 44 429 20 45 449 30 46 479 1 47 480 1 48 481 79 49 560 79 50 639 79 51 718 79 52 797 8 53 805 1 54 806 1 55 807 20 56 827 4 57 831 4 Compressing station.ISD: (1192 records) - Calculating statistics normal: 20 empty-space: 16 empty-zero: 12 empty-fill: 11 pre-space: 0 end-space: 12 intervall-fields: 5 zero: 7 Original trees: 57 After join: 17 - Compressing file 87.14% (/my/monty/tmp) ls -l station.* -rw-rw-r-- 1 monty my 127874 Apr 17 19:00 station.ISD -rw-rw-r-- 1 monty my 55296 Apr 17 19:04 station.ISM -rw-rw-r-- 1 monty my 5767 Apr 17 19:00 station.frm (my/monty/tmp) isamchk -dvv station ISAM file: station Isam-version: 2 Creation time: 1996-03-13 10:08:58 Recover time: 1997-04-17 19:04:26 Data records: 1192 Deleted blocks: 0 Datafile: Parts: 1192 Deleted data: 0 Datafilepointer (bytes): 3 Keyfile pointer (bytes): 1 Max datafile length: 16777215 Max keyfile length: 131071 Recordlength: 834 Record format: Compressed table description: Key Start Len Index Type Root Blocksize Rec/key 1 2 4 unique unsigned long 10240 1024 1 2 32 30 multip. text 54272 1024 1 Field Start Length Type Huff tree Bits 1 1 1 constant 1 0 2 2 4 zerofill(1) 2 9 3 6 4 no zeros, zerofill(1) 2 9 4 10 1 3 9 5 11 20 table-lockup 4 0 6 31 1 3 9 7 32 30 no endspace, not_always 5 9 8 62 35 no endspace, not_always, no empty 6 9 9 97 35 no empty 7 9 10 132 35 no endspace, not_always, no empty 6 9 11 167 4 zerofill(1) 2 9 12 171 16 no endspace, not_always, no empty 5 9 13 187 35 no endspace, not_always, no empty 6 9 14 222 4 zerofill(1) 2 9 15 226 16 no endspace, not_always, no empty 5 9 16 242 20 no endspace, not_always 8 9 17 262 20 no endspace, no empty 8 9 18 282 20 no endspace, no empty 5 9 19 302 30 no endspace, no empty 6 9 20 332 4 allways zero 2 9 21 336 4 allways zero 2 9 22 340 1 3 9 23 341 8 table-lockup 9 0 24 349 8 table-lockup 10 0 25 357 8 allways zero 2 9 26 365 2 2 9 27 367 2 no zeros, zerofill(1) 2 9 28 369 4 no zeros, zerofill(1) 2 9 29 373 4 table-lockup 11 0 30 377 1 3 9 31 378 2 no zeros, zerofill(1) 2 9 32 380 8 no zeros 2 9 33 388 4 allways zero 2 9 34 392 4 table-lockup 12 0 35 396 4 no zeros, zerofill(1) 13 9 36 400 4 no zeros, zerofill(1) 2 9 37 404 1 2 9 38 405 4 no zeros 2 9 39 409 4 allways zero 2 9 40 413 4 no zeros 2 9 41 417 4 allways zero 2 9 42 421 4 no zeros 2 9 43 425 4 allways zero 2 9 44 429 20 no empty 3 9 45 449 30 no empty 3 9 46 479 1 14 4 47 480 1 14 4 48 481 79 no endspace, no empty 15 9 49 560 79 no empty 2 9 50 639 79 no empty 2 9 51 718 79 no endspace 16 9 52 797 8 no empty 2 9 53 805 1 17 1 54 806 1 3 9 55 807 20 no empty 3 9 56 827 4 no zeros, zerofill(2) 2 9 57 831 4 no zeros, zerofill(1) 2 9 Adding functions to *MySQL* *************************** Adding new functions to *MySQL* =============================== You have two ways to add new functions to mysql: * You can add the function trough the new UDF interface. *Note UDF functions:: * You can add this as a native MySQL function. To add a new native *MySQL* function (like `SOUNDEX()'), you only have to do the following: 1. Add one line in `sql_lex.cc' defining the function name in the `sql_functions' array. 2. Add two lines in `sql_yacc.y'. On defines the preprocessor symbol yacc can define (this should be added at the beginning of the file). Then define the function parameters and create an 'item' with these parameters. Check, for example, all occurrences of SOUNDEX in `sql_yacc.y' 3. In item_func.h declare a class inheriting from Item_num_func or Item_str_func depending on whether your function returns a number or a string. 4. In `item_func.cc' add: `double *Item_func_newname::val()' If you are defining a number function or `String *Item_func_newname::Str(String *str)' if you are defining a string function. 5. You should probably also define the following function: `void Item_func_newname::fix_length_and_dec()' This should at least calcutate `max_length' based on the given arguments. `max_length' is the maximum number of chars the function may return. If the function can't return a `NULL', one should set `maybe_null = 0'. About string functions: 1. For string functions the `String *str' argument provides a string buffer that may be used to hold the result. 2. A string function should return the string that holds the result. 3. All current string functions try to avoid allocating any memory unless absolutely necessary! ODBC **** Which operating systems does *MySQL* ODBC support? ================================================== *MySQL* ODBC is a 32 bit ODBC (2.50) level 0 driver for Windows95 and NT. We hope somebody will port it to Windows 3.x. How should I report problems with *MySQL* ODBC? =============================================== We have only tested ODBC with Admndemo, some C programs, Msquery and Excel. To give some light about any problem we would like to have the log file from the ODBC manager (the log you get when requesting logs from ODBCADMIN) and a MYODBC log. To get a MYODBC log, please add 4 to the 'Options' argument on the MyODBC connect/configure screen. The log will be written to file `c:\tmp\myodbc.log'. Programs known to work with MyODBC. =================================== Most programs should work with MyODBC, but we we have tested these ourselves or got a confirmation from some user that is works: Program Comment Access To make Access work: * You should have a primary key in the table. * You should have a timestamp. * Only use double float fields. Access fails when comparing with single floats. * Set 2 in the options field when connection to *MySQL*. Excel Works. Some tips * If you have problems with dates try to select them as strings. SELECT concat(sunrise_time), concat(sunset_time) FROM sunrise_sunset; Values returned in this format (string) should be correctly recognised by Excel97 as time values. What `concat()' does in this case is that it fools ODBC to think the column is of 'string type'. Without the 'concat()' ODBC knows the column is of time type. Excel does not understand that. Note that this is a bug in Excel because it automaticly converts a string to a time. This would be great if the source was a text file, but this is plain stupid when the source is a ODBC connection which reports exact types for each column. odbcadmin Test program for ODBC. Delphi One must use DBE 3.2 or newer. C++Builder Tested with BDE 3.0. The only known problem is that when the table schema changes, query fields are not updated. BDE however does not seem to recognise primary keys, only the index PRIMARY, though this has not been a problem. How do I fill in the various fields in the ODBC administrator program? ====================================================================== There are three possibilities for specifying the server name on Windows95: 1. Use the IP address of the server. 2. Add a file lmhosts with the following info: `ip hostname' For example: 194.216.84.21 my 3. Configure the PC to use DNS. Example of how to fill in the 'ODBC setup'. Windows DNS name: test Description: This is my test database MySql Database: test Server: 194.216.84.21 User: monty Password: my_password Port: The 'Windows DNS name' is any name that is unique in your windows ODBC setup. When you fill in the values in the ODBC setup, these will be used as default values when prompting for a Driver connect. You don't have to give 'server', 'user' or 'password' in the ODBC setup screen. When connecting to an ODBC source you have the option to change the server, user, password and port. If port is not given the default port (3306) is used. How to get the value of a AUTO_INCREMENT column in ODBC ======================================================= A common problem is how to get the value of an automatically-generated id from an `INSERT'. With ODBC you can do something like this: INSERT INTO foo (auto,text) VALUES(NULL,'text') select LAST_INSERT_ID() or if you are just going to insert in into another table: INSERT INTO foo (auto,text) VALUES(NULL,'text') INSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),'text') Problems and common errors ************************** Some common errors when using *MySQL* ===================================== `MySQL server has gone away' error. ----------------------------------- The most common reason for the `MySQL server has gone away' error is that the server closed the connection because of a timeout. By default the server closes the connection after 8 hours if nothing has happened. If you have a script you just have to issue the query again for the client to do a automaticly reconnection. One normally can get these error codes in this case: (Which one you get is OS dependent) CR_SERVER_GONE_ERROR The client couldn't send a question to the server. CR_SERVER_LOST The client didn't get an error when writing to the server but it didn't get full answer (or any answer) to the question. You can also get this error if you send a wrong or too big query to the server. If mysqld gets a wrong block it assumes that something has gone wrong with the client and closes the connection. If you need big queries, if you are for example working with big blobs, you can increase the query limit by starting mysqld with the option `-O max_query_size=#' (default 65536). The extra memory is allocated by demand, so mysqld will only use more memory when you issue a big query or when mysqld must return a big result row! `Can't connect to local MySQL server' error. -------------------------------------------- A *MySQL* client can connect to the mysqld server in two different ways: Unix sockets, which connects trough a file in the file system, (default `/tmp/mysqld.sock'), or TCP/IP which connects trough a port number. Unix sockets are faster than TCP/IP but can only be used when connection to a server on the same computer. Unix sockets are used if one doesn't specify a hostname or if one specifies the special hostname 'localhost'. Here follows some reasons to the error `Can't connect to local MySQL server'. * You don't have a mysqld running. Check that you have a process named 'mysqld' running with `ps'. You can check the server by trying these different connections: (the port and socket may of course be different in your setup). mysqladmin version mysqladmin -h `hostname` version mysqladmin -h `hostname` --port=3306 version mysqladmin --socket=/tmp/mysql.sock version * You are running on a system that uses mit-threads. Mit threads doesn't support sockets. If you are running on a system that doesn't have native threads mysqld uses the mit-thread package. *Note Which OS::. When using MIT threads you must always give the hostname when connecting to the server. Try using `'mysqladmin -u `hostname` version' to check the connection to the server. * Someone has removed the unix socket mysqld uses. You may have a cron job that removes the mysql socket (default `/tmp/mysqld.sock'). You can always run `mysqladmin version' and check that the socket mysqladmin is trying to use really exists. The fix in this case is to change the cron job not to remove mysqld.sock or to place the socket somewhere else. You can move the socket by reconfiguring mysqld with `./configure --with-unix-socket-path=/my-own-place/mysql.sock' or starting safe_mysqld with `--socket=/my_own_place/mysqld.sock' and setting the environment variable `MYSQL_UNIX_PORT' to point at the socket before starting your mysql clients. * You have started the mysqld server with `--socket=...'. If you change the socket you must also notify the clients about the new path. You can do this by setting the environment variable `MYSQL_UNIX_PORT' to point at the socket or provide the socket as a argument to the mysql clients. You can for example test the socket with `mysqladmin --socket=/path-to-socket version'. Out of memory errors -------------------- If you do a query and get something like the following error: mysql: Out of memory at line 42, 'malloc.c' mysql: neaded 8136 byte (8k), memory in use: 12481367 bytes (12189k)) ERROR 2008: MySQL client got out of memory Note that the error refers to the *MySQL* client. The reason for this error is simply that the client does not have enough memory to store the whole result. Packet to large --------------- When the client gets a block bigger that `net_buffer_length' it issues a `Packet too large' error. If the `mysql' client is used you may set a bigger buffer by starting the client with `mysql --set-variable= net_buffer_length=1m'. The table is full ----------------- This error occurs when an in-memory temporary table gets bigger than `tmp_table_size'. To avoid this problem one can increase the `-O tmp_table_size=#' option to mysqld or use the SQL option `SQL_BIG_TABLES' before you do the problem query. *Note Set option::. One can also start mysqld with the option: `--big-tables'. This is exactly the same as using SQL_BIG_TABLES for all queries. Commands out of sync in client ------------------------------ If you get `Commands out of sync; You can't run this command now' in you client code you are calling clients functions in the wrong order! This can for example happen if you are using 'mysql_use_result()' and try to execute a new query before you have done a 'mysql_free_result()'. This can also happen if you try to execute two queries, that returns data, without a mysql_use_result() or mysql_store_result() between. How does *MySQL* handle a full disk =================================== On a disk full condition *MySQL* does the following: It checks once every minute if there is enough space to write the current row. If there is enough disk it continues as if nothing had happened. * Every 6 minutes it writes a entry to the log file warning about disk full. * To continue you have only to free enough free space to insert all records. * To abort the thread you have to send a `mysqladmin kill' to the thread. The thread will be aborted when it checks the disk next time (in 1 minute). * Note that other threads may be waiting for the table that caused 'disk full'. If you have a lot of 'locked' threads killing the one thread that waits for disk full will allow the other threads to continue. `Access denied?' error. ======================= *Note Privileges::. And especially *Note Access denied::. How to run *MySQL* as a normal user. ==================================== mysqld (the *MySQL* server) can run as any user. In order to change mysqld to run as user USER, you'd have to the following: * Stop the server if it's running * Change the database directories so that USER has read and write privileges privileges to them: `shell> chown -R USER /your/path/to/mysql/var' * start the server as user USER * If you are using mysql.server to start mysqld when the system is rebooted, you should change mysql.server to call 'su' to user USER. * You don't have to do anything to safe_mysqld to not run as root. At this point, your mysqld process should be running fine and dandy as user 'USER'. One thing hasn't changed though - the access permissions. By default (right after running the permissions table install script), only user 'root' has access permission to the database. Unless you have changed that, it's still true. This shouldn't stop you from accessing *MySQL* when you're logged in under a user other than root, just specify -u root to the client program. Note that accessing *MySQL* as root, by supplying -u root in the command line, doesn't have ANYTHING to do with *MySQL* running as root, as a user or as anyone else. The access permissions and userbase of *MySQL* are completely separate from the UNIX users. The only connection to the UNIX users is if you don't use the -u option to clients. In this case the client will try to login into *MySQL* with your UNIX login name. If your UNIX box itself isn't secured, you should probably at least put a password on the root users in the *MySQL* access tables, since any johndoe user can run 'mysql -u root dbname' and do whatever he likes. Problems with file permissions ============================== If you have problems with file permissions, for example when creating a table mysql gives: "ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13)", then you might have the wrong value for environment variable UMASK. Default umask is 0664. Fix: UMASK=432 export UMASK ./bin/safe_mysqld File not found ============== If you get `ERROR '...' not found (Errcode 23)' or any other error with `errcode 23' from *MySQL* this means that you haven't allocated enough file descriptors for *MySQL*. `perror #' will give you the error message in a more readable form. There is a commented line `ulimit -n 256' in `safe_mysqld'. You can remove this comment and of course increase or decrease the value if you want. You can also make the table cache smaller with: `safe_mysqld -O table_cache=32' (the default is 64). Problems using DATE columns. ============================ The format of DATE is 'YYYY-MM-DD'. According to ANSI SQL nothing else is allowed. One should use this format to update or in the WHERE clause, ie `select * from table_1 where date >= '1997-05-05''; As a convenience, *MySQL* automatically converts the date to a number if used in a number context. It is also smart enough to allow a 'relaxed' string form when updating and in a `WHERE' with a compare to a `TIMESTAMP', `DATE' or a `DATETIME' column. The special date '0000-00-00' can be stored and retrieved as 0000-00-00. When using a '0000-00-00' date trough MyODBC it will automaticly be converted to NULL in MyODBC 2.50.12 and above, because ODBC can't handle this kind of dates. This means that the following works: insert into table_1 (idate) values (19970505) ; insert into table_1 (idate) values ('19970505') ; insert into table_1 (idate) values ('97-05-05'); insert into table_1 (idate) values ('1997.05.05'); insert into table_1 (idate) values ('1997 05 05'); insert into table_1 (idate) values ('0000-00-00'); select idate from table_1 where idate >= '1997-05-05'; select idate from table_1 where idate >= 19970505; select mod(idate,100)1 from table_1 where idate >= 19970505; select idate from table_1 where idate >= '19970505'; The following will not work: select idate from table_1 where strcmp(idate,'19970505')=0; Because '19970505' is compared as a string to '1997-05-05'. Note that *MySQL* does no checking if the date is correct. If you store a wrong date, like 1998-2-31, the wrong date will be stored. If the date is totally impossible a 0 is stored in the date field.. This is mainly a speed issue and we think it's up to the application to check the dates and not the server. Case sensitivity in searches. ============================= By default a *MySQL* column is case insensitive (although there are some character sets that never are case insensitive). That means that if you search with `column like 'a%';' you will get all columns that start with `A' or `a'. If you want to make this search case sensitive use something like `INDEX(column, "A")=0' to check a prefix. Or `STRCMP(column, "A") = 0' if the whole string should be the same. Simple compare operations `>=, >, = , < , <=', sorting and grouping are done on the characters 'sort value'. Characters with the same sort value (like E, e and й) are treated as the same character! LIKE comparing is done on the uppercase value of each character (E == e but E <> й) If you want `column' to always be treated in a case sensitive manner, declare it as `BINARY'. *Note Create table::. If you are using Chinese data in the so-called big5 encoding you want to make all character columns `BINARY'. This works because the sorting order of big5 encoding characters is based on the order of ascii codes. Problems with NULL ================== A common confusion for newcomers to SQL is that they think that NULL is the same things as a empty string ". This is not the case! For example the following statements are compleatly different: INSERT INTO my_table (name,phone) values ("my",NULL); INSERT INTO my_table (name,phone) values ("my",""); The first inserts a NULL value into address and the second inserts an empty string into address. The first can be regarded as 'phone number is not known' and the second can be regarded as 'she has no phone'. In SQL NULL is a value that is always false when comparing to all other values, even NULL. An expression that contains NULL will always produce a NULL value if nothing else is mentioned. All following columns return NULL: SELECT NULL,1+NULL,CONCAT('Invisible',NULL); If you want to search for a column that has NULL, you must use the IS NULL test. The following shows how to find the NULL phone number and the empty phone number: SELECT * from my_table where phone IS NULL; SELECT * from my_table where phone = ""; In *MySQL*, as in many other SQL servers, you can't index columns that can have `NULL' values. You have to declare such columns `NOT NULL'. When reading data with `LOAD DATA INFILE' empty columns are updated with ". If you want a NULL value in a column you should use NULL or \N in the textfile. When using `ORDER BY' NULL values are presented first (if not using DESC). When using `GROUP BY' all NULL values are regarded as equal. To help with NULL handling you can use the functions: `IS NULL', `IS NOT NULL' and `IFNULL()' Solving some common problems with *MySQL* ***************************************** Database replication ==================== The most general way to do database replication is using the update log. *Note Update log::. This requires that one database acts as a master (all data changes are done here) and one or more others as slaves. To update a slave just run `mysql < update_log'. If you never do deletes, you can use timestamps. It is possible to make a two-way updating system using both the update log (for deletes) and timestamps (on both sides). But in that case you must be able to handle confilicts when the same data has been changed in both ends. You probably want to keep the old version to help with deciding what has been updated. Because replication in this case is done with SQL statements, you should not use the following functions in statements that updates the database, because they may return a different value in the other *MySQL* server: * DATABASE() * GET_LOCK() and RELEASE_LOCK(). * RAND() * USER(), SYSTEM_USER() or SESSION_USER(). * VERSION() All time functions are safe to use as the timestamp is sent to the mirror if needed. LAST_INSERT_ID() is also safe to use. Backup of databases =================== Since *MySQL* tables are stored as files it is easy to do a backup. To get a consistent backup, do a `LOCK TABLES' on the relevant tables. *Note Lock tables::. You only need a read lock so other threads can continue to query the tables while making a copy of the files in the database directory. Or if you want to make a SQL level backup you can use `SELECT INTO OUTFILE'. Another way is to use the `mysqldump' program. Do a full backup of your databases, with `mysqldump --tab=some-dir --lock-tables --quick ' or simply by copying all table files (.frm, .ISM and .ISD) while the server isn't updating anything. * start `mysqld' with `--log-update' * You will get log files with name of 'hostname'.# where # is a number that is increased for each reload. When you have to restore something (if `isamchk -r' can't restore all data as it can in 99.9% of all cases): * Restore the original mysqldump backup. * ls -1 -t -r hostname.* | xargs cat | mysql The ls in the last command is done to get all log files in the right order You can also do selective backups with `select * into outfile from table' and restore with `LOAD DATA FROM INFILE 'file_name' REPLACE ...'. To avoid duplicate records you need a `PRIMARY KEY' in the table. The `REPLACE' means that if there is a 'duplicate index' conflict when inserting new records the old record will be replaced with the new one. *MySQL* client tools and API's ****************************** *MySQL* C API ============= The `C' API is distributed with *MySQL*. It is included in the `libmysqlclinet' library. It allows `C' programs to access a database. Most of the other client APIs (all except Java) use this library to connect. So for example you can use the same environment variables. The client has a maximum communication buffer size. This is automatically increased up to the maximum size (the default for this is 512Kb). As buffers are increased (but not decreased until close) on demand, it will not take any resources if one increases this. This size check is mostly a check for erroneous queries and communication packets. The communication buffer must be big enough to contain a single SQL statement and one row of returned data (but of course not at the same time). Each thread's communication buffer is dynamically enlarged to handle any row or query up to the imposed limit. So if you have `BLOB's that contains data up to 16M you must have at least 16M as your communication buffer limit. *Note MySQL parameters::. MySQL shrinks each communication buffer to `net_buffer_length' after each query. *mysql_affected_rows* Retrieves the number of affected rows by the last UPDATE, DELETE or INSERT. *mysql_close* Closes a server connection. *mysql_connect* Establish a connection to a *MySQL* server. *mysql_create_db* Create a database. *mysql_data_seek* Seeks to an arbitrary row in a query result set. *mysql_drop_db* Drop a database. *mysql_eof* Determine if last row has been read. *mysql_escape_string* Escape a string for a SQL statement. *Note Base Syntax:: *mysql_error* The error message from last *MySQL* function. *mysql_fetch_field* Find out what type a table field is. *mysql_fetch_lengths* Returns the length of all columns in a query result set. *mysql_fetch_row* Fetch the 'next' row in the query result. *mysql_field_seek* Put the column cursor on column number field. *mysql_free_result* Free memory used to store a query result. *mysql_get_client_info* Return version information for the current client library. *mysql_get_host_info* Returns name of server host. *mysql_get_proto_info* Get protocol version used by connection. *mysql_get_server_info* Returns the version number of the server. *mysql_insert_id* Returns ID generated for a AUTO_INCREMENT field. *mysql_list_dbs* Return matching database names. *mysql_list_fields* Return matching field names. *mysql_list_processes* Get a list of the current server threads. *mysql_list_tables* Return matching table names. *mysql_num_fields* Return the number of columns in a result set. *mysql_num_rows* Returns the number of rows in result set. *mysql_query* Executes a SQL query. *mysql_real_query* Executes a SQL query with length information. *mysql_reload* Reload the user permissions table in the server. *mysql_select_db* Connect to a database. *mysql_shutdown* Shut down the database server. *mysql_stat* Return server status in a string. *mysql_store_result* Reads a result set to the client. *mysql_use_result* Initiate a dynamic result set for each row. This uses much less memory than `mysql_store_result()' but will put more strain on the server. `int *mysql_affected_rows*(MYSQL *mysql)' Retrieves the number of affected rows by the last UPDATE, DELETE or INSERT. `void *mysql_close*(MYSQL *mysql)' Closes a server connection. `MYSQL **mysql_connect*(MYSQL *mysql, const char *host, const char *user, const char *passwd)' Establish a connection to a *MySQL* server. `int *mysql_create_db*(MYSQL *mysql, const char *db)' Create a database. `void *mysql_data_seek*(MYSQL_RES *res, uint offset)' Seeks to an arbitrary row in a query result set. `int *mysql_drop_db*(MYSQL *mysql, const char *db)' Drop a database. `int *mysql_eof*(MYSQL_RES *)' Determine if last row has been read. `char **mysql_error*(MYSQL *mysql)' The error message from last *MySQL* function. `uint *mysql_escape_string*(char *to,char *from,uint length)' Escape a string for a SQL statement. `MYSQL_FIELD **mysql_fetch_field*(MYSQL_RES *handle)' Find out what type a table field is. When querying for the length of a `BLOB' without retreving a result, *MySQL* returns the 'default blob length', which is 8192, when doing a select on the table. When one retrevies a result, column_object->max_length contains the real max_length for the specific query. The 8192 size is chosen because *MySQL* doesn't know the max length for the `BLOB'. This should be made configurable sometime. `unsigned int **mysql_fetch_lengths*(MYSQL_RES *mysql)' Returns the length of all columns in a query result set. `MYSQL_ROW *mysql_fetch_row*(MYSQL_RES *mysql)' Fetch the 'next' row in the query result. `void *mysql_field_seek*(MYSQL_RES *result, int field)' Put the column cursor on column number field. `void *mysql_free_result*(MYSQL_RES *result)' Free memory used to store a query result. `char **mysql_get_client_info*(void)' Return version information for the current client library. `char **mysql_get_host_info*(MYSQL *mysql)' Returns name of server host. `int *mysql_get_proto_info*(MYSQL *mysql)' Get protocol version used by connection. `char **mysql_get_server_info*(MYSQL *mysql)' Returns the version number of the server. `int *mysql_insert_id*(MYSQL *mysql)' Returns ID generated for AUTO_INCREMENT field. `MYSQL_RES **mysql_list_dbs*(MYSQL *mysql, const char *wild)' Return matching database names. `MYSQL_RES **mysql_list_fields*(MYSQL *mysql, const char *table, const char *wild)' Return matching field names. `MYSQL_RES **mysql_list_processes*(MYSQL *mysql)' Get a list of the current server threads. `MYSQL_RES **mysql_list_tables*(MYSQL *mysql, const char *wild)' Return matching table names. `int *mysql_num_fields*(MYSQL_RES *result)' Return the number of columns in a result set. `int *mysql_num_rows*(MYSQL_RES *result)' Returns the number of rows in result set. `int *mysql_query*(MYSQL *mysql, const char *query)' Executes a SQL query. `int *mysql_real_query*(MYSQL *mysql, const char *query, uint length)' Executes a SQL query with length information. `int *mysql_reload*(MYSQL *mysql)' Reload the user permissions table in the server. `int *mysql_select_db*(MYSQL *mysql, const char *db)' Connect to a database. `int *mysql_shutdown*(MYSQL *mysql)' Shut down the database server. `char **mysql_stat*(MYSQL *mysql)' Return server status in a string. `MYSQL_RES **mysql_store_result*(MYSQL *mysql)' Reads a result set to the client. `MYSQL_RES **mysql_use_result*(MYSQL *mysql)' Initiate a dynamic result set for each row. Why is it that after `mysql_query()' returns success, `mysql_store_result()' sometimes returns NULL? ---------------------------------------------------------------------------------------------------- It means one of the following: 1. Malloc failure. 2. The data couldn't be read (Error on connection). 3. The statement was a statement which never returns data (`INSERT' or `UPDATE' or `DELETE'). You can always check if the statement should have given a result by checking that `mysql_num_fields(MYSQL *)' isn't 0. If this is 0 the last query was a statement that does not return values. For example a `INSERT' or a `DELETE'. You have got an error if `mysql_error(MYSQL *)' isn't empty! What results can I get from a query? ------------------------------------ `mysql_affected_rows(MYSQL *)' returns the number of affected rows in the last query when doing an `INSERT', `UPDATE' or `DELETE'. Except, if `DELETE' is used without a `WHERE' clause then the table is truncated which is much faster! In this case it returns the number of records affected as zero. `mysql_insert_id(MYSQL *)' returns the given ID of the last query when inserting a row into a table with an `AUTO_INCREMENT' index. *Note mysql_insert_id:: Some queries, `LOAD DATA INFILE...' and `INSERT INTO ... SELECT ...', return additional info. The result is returned in `mysql_info(MYSQL *)'. `mysql_info()' returns a null pointer if there is no additional information. How can I get the unique ID for the last inserted row? ------------------------------------------------------ If you insert a record that has a `AUTO_INCREMENT' index then you can get the given id with `mysql_insert_id(MYSQL *)'. The last value is also stored in the server and can be retrieved with the `LAST_INSERT_ID()' function. You can check if an auto_increment index is used by the following code. This also checks if the query was an `INSERT' with an `auto_increment' index. if (mysql_error(MYSQL)[0] == 0 && mysql_num_fields(MYSQL_RESULT) == 0 && mysql_insert_id(MYSQL) != 0) used_id = mysql_insert_id(MYSQL); The id that `LAST_INSERT_ID()' returns is maintained in the server per connection. It will not be botched by another client. It will not even be changed if you update another auto_increment column with a non magic value (that is a not NULL or 0). What is the difference between `mysql_use_result()' and `mysql_store_result()' modes? ------------------------------------------------------------------------------------- `mysql_use_results' reads the result directly from the server without storing it in a temporary table or local buffer. This is somewhat faster and uses much less memory than `mysql_store_result'. One shouldn't use `mysql_use_results' if there is a lot of processing being done for each row at the client side, or if the output is sent to a screen on which the user may do a ^S (stop scroll). Doing this would tie up the server and then other threads couldn't update the used tables. One can't use `mysql_data_seek' `mysql_num_rows' or issue other queries while using `mysql_use_result'. When using `mysql_use_result' one must execute `mysql_fetch_row()' until one gets a NULL pointer back, because else the next query would get results from the previous query. The C API will give the error: `Commands out of sync; You can't run this command now', if you forget to do this! Problems linking with the C API. -------------------------------- When linking with the C API you can get the following errors on some systems: gcc -g -o client test.o -L/usr/local/lib/mysql -lmysqlclient -lsocket -lnsl Undefined first referenced symbol in file floor /usr/local/lib/mysql/libmysqlclient.a(password.o) ld: fatal: Symbol referencing errors. No output written to client This means that on your system you have to include the math library (-lm) last in the compile/link line. How to make a threadsafe client ------------------------------- The client is 'almost' thread-safe. The biggest problem is that net.c (the subroutines that read from sockets) are not interrupt safe. This was done with the thought that one may want to have one's own alarm that can break a long read to a server. The standard client libraries are not compiled with the thread options. To get a thread safe client use the `-lmysys', `-lstring' and `-ldbug' libraries and `net_serv.o' that the server uses. When using a threaded client I think one can have great use of the thr_alarm.c routine. If you are using the mysys routines, the only thing one has to remember is to call my_init() first! Making a threadsafe client -------------------------- All functions except mysql_connect() are currently thread safe. To get connect thread_safe you have to do the following: Recompile the client with: CPPFLAGS=-DTHREAD_SAFE_CLIENT ./configure ... You may get some errors because of undefined symbols when linking the standard client as the pthread libraries are not included by default. The resulting libmysqld.a library is now thread safe. Two threads can't use the same handle (returned by `mysql_connect()') at the same time, even if two threads can use different `MYSQL_RES' handles that were created with `mysql_store_result()'. When using a threaded client one can have great use of the thr_alarm.c routine. If you are using the mysys routines, the only thing one has to remember is to call my_init() first! *MySQL* Perl API's ================== Since `DBI/DBD' now is the recommended perl interface mysqlperl is not documented here. `DBI' with `DBD::mysql' ----------------------- `DBI' is a generic interface for many databases. That means that you can write a script what works with many different database engines without change. You need a DataBase Driver (DBD) defined for each database type. For *MySQL*, this driver is called `DBD::mysql'. For more information on the Perl5 DBI, please visit DBIs web page (http://www.hermetica.com/technologia/DBI/) and read the documentation. For more information on Object Oriented Programming (OOP) as defined in Perl5, see the perl OOP page (http://language.perl.com/info/documentation.html). The DBI interface ................. *Portable DBI methods.* connect Establish a connection to a database server prepare Get a SQL statement ready for execution do Prepares and executes a SQL statement disconnect Disconnect from the database server quote Quote strings/blobs to be inserted execute Executes prepared statements fetchrow_array fetch the next row as an array of fields. fetchrow_arrayref fetch next row as a reference array of fields fetchrow_hashref fetch next row as a reference to a hashtable fetchall_arrayref Get all data as a array of arrays finish finish a statment and let the system free resources rows Returns the number of rows affected data_sources Return an array of databases available on localhost ChopBlanks Shall fetchrow trim spaces NUM_OF_PARAMS Number of placeholders in the prepared statement NULLABLE Which columns can be NULL *MySQL specific methods.* insertid The latest auto_increment value is_blob Which column ar BLOBs is_key Which columns are keys is_num Which columns are numeric is_pri_key Which columns are primary keys is_not_null Which columns can NOT be NULL. See NULLABLE length Maximum theoretically possible column sizes max_length Maximum physical present column sizes NAME Column names NUM_OF_FIELDS Number of fields returned. table Table names in returned set type All coulumn types _CreateDB Create a database _DropDB Drop a database. *THIS IS DANGEROUS* `connect' You use the connect method to make a database connection to the data source. The `$data_source' value should begin with `DBI:driver_name:'. Example connect methods with the `DBD::mysql' driver: $dbh = DBI->connect("DBI:mysql:$database", $user, $password); $dbh = DBI->connect("DBI:mysql:$database:$hostname", $user, $password); $dbh = DBI->connect("DBI:mysql:$database:$hostname:$port", $user, $password); If the username and/or password are undefined, then the DBI will use the values of the `DBI_USER', `DBI_PASS' environment variables respectively. If you don't specify a hostname, then it will default to `"localhost"'. If you don't specify a port, then it defaults to the default mysql port (3306). `prepare' Prepare gets a SQL statement ready for execution by the database engine and returns a statement handle `($sth)' which invokes the execute method. Example: $sth = $dbh->prepare($statement) or die "Can't prepare $statement: $dbh->errstr\n"; `do' The "do" method prepares and executes a SQL statement and returns the number of rows effected. This method is generally used for "non-select" statements which can not be prepared in advance (driver limitation) or which do not need to executed more than once (inserts, deletes, etc.). Examples: $rc = $dbh->do($statement) or die "Can't execute $statement: $dbh- >errstr\n"; `disconnect' Disconnect will disconnect the database handle from the database. This is typically called right before you exit from the program. Example: $rc = $dbh->disconnect; `quote' The quote method is used to "escape" any special characters contained in the string and to add the required outer quotation marks. $sql = $dbh->quote($string) `execute' This method executes the prepared statement. For non-select satements, it returns the number of rows affected. For select statements, execute only starts the SQL query in the database. You need to use one of the `fetch_*' methods below to retrieve the data. Example: $rv = $sth->execute or die "can't execute the query: $sth->errstr; `fetchrow_array' This method "fetches" the next row of data and returns it as an array of field values. Example: while(@row = $sth->fetchrow_array) { print qw($row[0]\t$row[1]\t$row[2]\n); } `fetchrow_arrayref' This method "fetches" the next row of data and returns it as a reference to an array of field values. Example: while($row_ref = $sth->fetchrow_arrayref) { print qw($row_ref->[0]\t$row_ref->[1]\t$row_ref->[2]\n); } `fetchrow_hashref' This method fetches a row of data and returns a reference to a hash table containing field name/value pairs. This method is not nearly as efficient as using array references as demonstrated above. Example: while($hash_ref = $sth->fetchrow_hashref) { print qw($hash_ref->{firstname}\t$hash_ref->{lastname}\t\ $hash_ref- > title}\n); } `fetchall_arrayref' This method is used to get all the data (rows) to be returned from the SQL statement. It returns a reference to an array of arrays of references to each row. You access/print the data by using a nested loop. Example: my $table = $sth->fetchall_arrayref or die "$sth->errstr\n"; my($i, $j); for $i ( 0 .. $#{$table} ) { for $j ( 0 .. $#{$table->[$i]} ) { print "$table->[$i][$j]\t"; } print "\n"; } `finish' Indicates that no more data will be fetched from this statement handle. You call this method to free up the statement handle and any system resources it may be holding. Example: $rc = $sth->finish; `rows' Returns the number of rows affected (updated, deleted, etc.) from the last command. This is usually used after a do() or non-select execute() statement. $rv = $sth->rows; `NULLABLE' A reference to an array of boolean values; TRUE indicates that this column may contain NULLs. $null_possible = $sth->{NULLABLE}; `NUM_OF_FIELDS' Number of fields returned by a SELECT or LISTFIELDS statement. You may use this for checking whether a statement returned a result: A zero value indicates a non-SELECT statement like INSERT, DELETE or UPDATE. $nr_of_fields = $sth->{NUM_OF_FIELDS}; `data_sources' This method returns an array of databases available to the mysql daemon on localhost. @dbs = DBI->data_sources("mysql"); `ChopBlanks' This determines whether a fetchrow will chop preceding and trailing blanks off the returned values. $sth->{'ChopBlanks') =1; *MySQL specific methods.* `insertid' If you use the auto-increment feature of mysql, the new auto-incremented values will be stored here. $new_id = $sth->{insertid}; `is_blob' Reference to an array of boolean values; TRUE indicates that the respective column is a blob. $keys = $sth->{is_blob}; `is_key' Reference to an array of boolean values; TRUE indicates, that the respective column is a key. $keys = $sth->{is_key}; `is_num' Reference to an array of boolean values; TRUE indicates, that the respective column contains numeric values. $nums = $sth->{is_num}; `is_pri_key' Reference to an array of boolean values; TRUE indicates, that the respective column is a primary key. $pri_keys = $sth->{is_pri_key}; `is_not_null' A reference to an array of boolean values; FALSE indicates that this column may contain NULLs. You should better use the NULLABLE attribute above which is a DBI standard. $not_nulls = $sth->{is_not_null}; `max_length' `length' A reference to an array of maximum column sizes. The max_length is the maximum physically present in the result table, length gives the theoretically possible maximum. $max_lengts = $sth->{max_length}; $lengts = $sth->{length}; `NAME' A reference to an array of column names. $names = $sth->{NAME}; `table' Returns a reference to an array of table names. $tables = $sth->{table}; More DBI/DBD information ........................ You can use the perldoc command to get more information about DBI. perldoc DBI perldoc DBI::FAQ perldoc mysql You can also use the `pod2man', `pod2html', etc.. tools to translate to other formats. And of course you can find the latest DBI information at http://www.hermetica.com/technologia/DBI/, the DBI web page And of course you can find the latest DBI information at the DBI web page t table, length gives the theoretically possible maximum. . ement like INSERT, DELETE or UPDATE. [$j]\t"; } print "\n"; } amples: 6). port (http://www.hermetica.com/technologia/DBI/). *MySQL* Java connectivity (JDBC) ================================ Insert pointers/descriptions of JDBC. *MySQL* PHP API's ================= PHP documentation (http://www.php.net/manual/ref.mysql.php3) *MySQL* C++ API's ================= Insert pointers/descriptions for C++. *MySQL* Python API's ==================== Insert pointers/descriptions for Python. *MySQL* TCL API's ================= Insert pointers/descriptions for TCL. How does *MySQL* compare with other databases ********************************************* How does *MySQL* compare with `mSQL' ==================================== This section has been written by the *MySQL* developers so it should be read with that in mind. But there are NO factual errors that we know of. For a list of all supported limits, functions and types see the crash-me web page (http://www.tcx.se/crash-me.html). *Performance.* For a true comparison of speed see the growing *MySQL* benchmark suite. *Note Benchmarks:: *MySQL* is significantly quicker on complex selects. `mSQL' can get patalogically slow if you chage the order of tables in a select. In the benchmark suite a time more that 15000 times slower than *MySQL* was seen. Because of no thread creation overhead, small parser, few features and simple security `mSQL' should be quicker at: Test that do a lot of connect/disconnect with a very simple query. Inserts into very simple tables with few columns and keys. * `CREATE TABLE' and `DROP TABLE'. * `SELECT' one something that isn't an index. (A table scan is very easy) As these operations are so simple, it is hard to be better at them when you have a higher start overhead. After the connection is established *MySQL* should perform much better. *MySQL* on the other hand is much faster than `mSQL' and most other SQL implementions on the following: Retrieving large results (*MySQL* has a better, faster and safer protocol) * Tables with variable length strings since *MySQL* has more efficent handling and can have indexes on varchars. * Handling tables with many columns. * Handling tables with large record lengths. * SELECT with many expressions. * SELECT on large tables. * Handles many connections at the same time. *MySQL* is fully multi-threaded. Each connection has it is own thread, which means that none of them has to wait for the other (unless a query modifying the same table you need to use is executed). In `mSQL' all other connections have to wait until the first, doesn't matter whether the query is long or short, is executed and finished. After that the next connection can be served, while all the others wait again, etc. * Joins (We have seen (*Note Benchmarks::) speed differences of 17000 times on this one). * `ORDER BY' and `GROUP BY'. * `DISTINCT'. * Using `TEXT' or `BLOB' columns. *SQL Features* 1. `GROUP BY' & `HAVING' *MySQL* supports a full `GROUP BY' with both `HAVING' and the following functions `count()', `avg()', `min()', `max()', `sum()' and `std()'. `min()' and `max()' may take string arguments. `count(*)' is optimised to return very quickly if this is the only thing in the query. `mSQL' does not support `GROUP BY' at all. 2. `INSERT' & `UPDATE' with calculations. *MySQL* can do calculations in a `INSERT' or `UPDATE'. UPDATE SET x=x*10+y WHERE x<20; 3. Aliasing *MySQL* has column aliasing. 4. Qualifying column names. If a column name is unique you do not have to use the full qualifier. 5. `SELECT' with functions *MySQL* has too many functions to list here. *Note Functions::. *Disk space efficiency* That is, how small can you make your tables. MySQL has very precise types so that use can create tables that take very little space. An example of a useful *MySQL* datatype is the mediumint that is 3 bytes long. If you have 10.000.0000 records even saving one byte per record is very important. Since `mSQL2' only has 4 types (char,text,int,real) it is hard to get small tables. *Stability* This is harder to judge objectively. For *MySQL* stability see *Note Stability::. We have no experience with `mSQL' stability so we can not say anything about that. *Price* Another important issue is of course the license. *MySQL* has a more flexible license than `mSQL' and is also cheaper than `mSQL'. Remember to at least consider paying for a license or email support for whatever product you choose to use. If you sell a product with *MySQL* you are of course required to get a license for this. *Perl interfaces* MySQL has basically the same interfaces to perl as `mSQL' with some added features. *JDBC (Java)* MySQL has a Java interface by GWE technologies that has been improved by Xiaokun Kelvin ZHU. We know that `mSQL' has one but we have too little experience with it to compare. *Rate of development* MySQL has a very small team of developers, but we are quite used to coding C and C++ very rapidly. Since threads, functions, group by and so on are still not implemented in `mSQL', it has a lot of catching up to do. To get some perspective on this you can view the `mSQL' HISTORY file for the last year and compare it with the News section. *Note News::. It should be pretty obvious which one has developed most rapidly. *Utility programs* Both `mSQL' and *MySQL* have a lot of interesting third-party tools. Since it is very easy to port upwars (`mSQL' -> *MySQL*) *MySQL* has almost all interesting `mSQL' applications. MySQL comes with a simple msql2mysql program that fixes the different spelling of the most used functions. A conversion of a client program from `mSQL' to mySQL usually takes a couple of minutes. How about `mSQL' tools like msql-tcl, msqljava? ----------------------------------------------- According to our experience it would just take a few hours to convert a tool using the `mSQL' C API to the *MySQL* C API. The procedure: 1. Run the shell script msql2mysql on the source. This needs the binary program replace, which is distributed with *MySQL*. 2. Compile 3. Fix all compiler errors: Differences between the *MySQL* and `mSQL' C API's. * MySQL uses *MySQL* as a connection type (`mSQL' uses an `int'). * MySQL connect takes a pointer to a MYSQL structure as a parameter. It is easy to define one globally or use malloc to get one. * mysql_connect takes 2 extra parameters. You may set these to NULL,NULL for default use (user and password). * mysql_error takes the MYSQL structure as a parameter. Just add the parameter to your old msql_error code if you are porting old code. * Some incompatibilities exist as a result of *MySQL* supporting multiple connections to the server from the same process. * *MySQL* returns an error number and a text for all errors. `mSQL' only returns a text error How different from `mSQL' are the *MySQL* client/server communications protocols? --------------------------------------------------------------------------------- There are enough differences that it is impossible (at least not easy) to support both. The greatest differences between *MySQL* and `mSQL' are: * A message buffer may contain many result rows. * The message buffers are dynamically enlarged if the question or the result is bigger than the current buffer up to a configurable server and client limit. * All packages are numbered to catch duplicated or missing packets. * All columns are sent in ASCII, the length of columns and rows are sent in packed binary coding (1,2 or 3 bytes). * MySQL can read in the result unbuffered (without having to store the full set in the client). * If a single write/read takes more than 30 seconds then the server closes the connection. * If nothing has happened on a connection for 8 hours the server closes the connection. What are the differences in the SQL syntax between *MySQL* & `mSQL' 2.0? ------------------------------------------------------------------------ * `CREATE TABLE' `*MySQL*' Has (among others) the following extra types: *Note Create table:: - `UNSIGNED' option for all integer columns. - `ZEROFILL' option for all integer columns. - `AUTO_INCREMENT' option for all integer columns that also is a `PRIMARY KEY'. *Note mysql_insert_id::. - `DEFAULT' value for all columns. - `ENUM' type for one of a set of strings. - `SET' type for many of a set of string. - `BIGINT' type for 64 bit integers. `mSQL2' `mSQL' type Corresponding *MySQL* type. char(len) char(len) text(len) text(len). len is the maximal length. And `LIKE' works. int int. With many more options! real real. Or float. Both 4 and 8 bytes versions are available. uint Unsigned integer. date date. Takes ANSI SQL format instead of `mSQL's own. time time money decimal(12,2). A fixed point value with two decimals. * To create indexes. `*MySQL*' All indexes have to be given to `CREATE TABLE'. Indexes can not be removed without recreating the table. *Note Alter table::. `mSQL' Indexes must be created by a separate `CREATE INDEX' clause. Indexes may be removed with `DROP INDEX'. * To get a unique identifier in a table at insert. `*MySQL*' Use `AUTO_INCREMENT' as a column type specifier. *Note mysql_insert_id::. `mSQL' Create a `SEQUENCE' on a table and select the `_seq' column. * To get a unique identifier for a row. `*MySQL*' Add a `PRIMARY KEY' to the table. `mSQL' Use the `_rowid' column. Observe that `_rowid' may change depending on many factors. * To get the time a column was last modified. `*MySQL*' Add a `TIMESTAMP' column to the table. This column will automaticly be updated to the current time if you don't give the column a value or if you give it a NULL value in a `UPDATE' or `INSERT' statement. `mSQL' Use the `_timestamp' column. * In mSQL NULL = NULL is TRUE. *MySQL* follows ANSI SQL and a comparison with NULL is always NULL. One has to change `=NULL' to `IS NULL' when porting old code from mSQL to *MySQL*. * All string comparisons are by default case independent with case according to ISO-8859-1 Latin1. If you don't like this you should declare your columns with the `BINARY' attribute. * Case insensitive searching. `*MySQL*' `LIKE' is case insensitive or case sensitive depending on the used columns. If possible *MySQL* uses indexes if the like argument doesn't start with a wildcard. `mSQL' Use `CLIKE'. * End space handling. `*MySQL*' Stripps all spaces att the end of `CHAR' and `VARCHAR' columns. Currently use a `TEXT' column if this behavior is undesired. `mSQL' Keeps end space. * What are the differences in the `WHERE' statement? `*MySQL*' *MySQL* does everything correctly prioritized (AND is evaluated before OR). To get `mSQL' behaviour in *MySQL*, use parenthesis: `select * from table where a=1 and b=2 or a=3 and b=4' -> `select * from table where (a=1 and (b=2 or (a=3 and (b=4))))'. `mSQL' Evaluates everything from left to right. That means that some logical calculations with more that 3 arguments can not be expressed in any way. This also mean that you have to change some queries when you upgrade to *MySQL*. You do this easy by adding parenthesis. Always when you are in doubt about what a query does: 1. Remove all distinct keywords to make the query easier to debug. 2. Write all columns from all tables to really see what you are doing. This will make it easier to see what goes wrong. * Access Control `*MySQL*' Has tables to store grant options per user, host and db. *Note Privileges:: `mSQL' Has a file `mSQL.acl' where you can grant read/write privileges for users. `' How does *MySQL* compare with PostgreSQL ======================================== For a list of all supported limits, functions and types see the crash-me web page (http://www.tcx.se/crash-me.html). PostgreSQL has some more advanced features like user-defined types, triggers, rules and transactions. But it lacks a lot of the standard types and functions from ANSI SQL and ODBC. See the crash-me web page (http://www.tcx.se/crash-me.html) for a complete list of supported/unsupported types/function. Normally PostgreSQL is much slower than *MySQL*. *Note Benchmarks::. Some users of *MySQL*. ********************** * Some Web search engines: - AAA Matilda Web Search (http://www.aaa.com.au) - What's New (http://www.whatsnu.com/) - Aladin (http://www.aladin.de/) - Columbus Finder (http://www.columbus-finder.de/) - Spider (http://www.spider.de/) - Blitzsuche (http://www.blitzsuche.de/) - Indoseek Indonesia (http://www.indoseek.co.id) - Yaboo - Yet Another BOOkmarker (http://www.yaboo.dk/) * Some Domain/Internet/Web and related services: - Registry over Web providers who supports *MySQL* (http://www.wix.com/mysql-hosting) - Monolith Internet Services (http://www.ml.org) runs *MySQL* supporting nearly a million rows and over 100,000 users. - Online Database (http://worldcommunity.com/ffwpu) - BigBiz Internet Services (http://www.bigbiz.com) - Fotball (Soccer) search page (http://www.soccersearch.com) - The Virt Gazette (http://virt.circle.net) * Internet information server (http://online.garant.ru) * AZC.COM's Feature Showcase (http://www.feature-showcase.com/htmls/demo_mysql.sql) * The Music Database (http://www.musicdatabase.com/) * Musical note-sheets (http://www.kiss.de/musik-mueller) * Bagism a John Lennon fan page (http://www.bagism.com) * Musician's looking for other musicians (Free Service) (http://TheMatrix.com/~matrix/band_search.phtml) * Course Search (http://www.teach.org.uk/subjects/trainingcourse/g.html) * Northerbys Online Auctions (http://www.northerbys.com) * Amsterdam Airport Schiphol (http://www.schiphol.nl/flights/home.htm) * CD database (http://TheMatrix.com/seventhsin/query.phtml) * Used Audio Gear Database (http://TheMatrix.com/~flmm/GEAR.html) * US Folk art broker (http://www.selftaught.com/) * Mail reading on the web (http://organizer.net/) * Free home pages on www.somecoolname.mypage.org (http://www.mypage.org/) * Der Server fьr Schulen im Web (In German) (http://www.schulweb.de/) * Auldhaefen Online Services (http://www.ald.net/) * CaryNET Information Center (http://www.cary.net/) * Dataden Computer Systems (http://www.dataden.com/) * Andrйemuseet (In Swedish) (http://andree.grm.se/) * HOMESITE Internet Marketing (http://www.him.net/) * Jade-V Network Services (http://www.jade-v.com/techinfo.html) * http://ww2010.atmos.uiuc.edu/(Gl)/abt/aknw/tech.rxml, Weather World 2010 Technical Credits * Weather World 2010 Technical Credits arch.phtml) nd over 100,000 users. d types and functions from ANSI SQL and ODBC. See the crash-me web page (http://www.tcx.se/crash-me.html) for a complete list of supported/unsupported types/function. thesis. he last year and compare it with the News section. *Note News::. It should be pretty obvious which one has developed most rapidly. hat the next connection can be served, while all the others wait again, etc. ther queries while using `mysql_use_result'. s root, as a user or as anyone else. The access permissions and userbase of *MySQL* are completely separate from the UNIX users. The only connection to the UNIX users is if you don't use the -u option to clients. In this case the client will try to login into *MySQL* with your UNIX login name. If your UNIX box itself isn't secured, you should probably at least put a password on the root users in the *MySQL* access tables, since any johndoe user can run 'mysql -u root dbname' and do whatever he likes. 1 1 2 2 4 3 6 4 4 10 1 5 11 20 6 31 1 7 32 30 8 62 35 9 97 35 10 132 35 11 167 4 12 171 16 13 187 35 14 222 4 15 226 16 16 242 20 17 262 20 18 282 20 19 302 30 20 332 4 21 336 4 22 340 1 23 341 8 24 349 8 25 357 8 26 365 2 27 367 2 28 369 4 29 373 4 30 377 1 31 378 2 32 380 8 33 388 4 34 392 4 35 396 4 36 400 4 37 404 1 38 405 4 39 409 4 40 413 4 41 417 4 42 421 4 43 425 4 44 429 20 45 449 30 46 479 1 47 480 1 48 481 79 49 560 79 50 639 79 51 718 79 52 797 8 53 805 1 54 806 1 55 807 20 56 827 4 57 831 4 Compressing station.ISD: (1192 records) - Calculating statistics normal: 20 empty-space: 16 empty-zero: 12 empty-fill: 11 pre-space: 0 end-space: 12 intervall-fields: 5 zero: 7 Original trees: 57 After join: 17 - Compressing file 87.14% (/my/monty/tmp) ls -l station.* -rw-rw-r-- 1 monty my 127874 Apr 17 19:00 station.ISD -rw-rw-r-- 1 monty my 55296 Apr 17 19:04 station.ISM -rw-rw-r-- 1 monty my 5767 Apr 17 19:00 station.frm (my/monty/tmp) isamchk -dvv station ISAM file: station Isam-version: 2 Creation time: 1996-03-13 10:08:58 Recover time: 1997-04-17 19:04:26 Data records: 1192 Deleted blocks: 0 Datafile: Parts: 1192 Deleted data: 0 Datafilepointer (bytes): 3 Keyfile pointer (bytes): 1 Max datafile length: 16777215 Max keyfile length: 131071 Recordlength: 834 Record format: Compressed table description: Key Start Len Index Type Root Blocksize Rec/key 1 2 4 unique unsigned long 10240 1024 1 2 32 30 multip. text 54272 1024 1 Field Start Length Type Huff tree Bits 1 1 1 constant 1 0 2 2 4 zerofill(1) 2 9 3 6 4 no zeros, zerofill(1) 2 9 4 10 1 3 9 5 11 20 table-lockup 4 0 6 31 1 3 9 7 32 30 no endspace, not_always 5 9 8 62 35 no endspace, not_always, no empty 6 9 9 97 35 no empty 7 9 10 132 35 no endspace, not_always, no empty 6 9 11 167 4 zerofill(1) 2 9 12 171 16 no endspace, not_always, no empty 5 9 13 187 35 no endspace, not_always, no empty 6 9 14 222 4 zerofill(1) 2 9 15 226 16 no endspace, not_always, no empty 5 9 16 242 20 no endspace, not_always 8 9 17 262 20 no endspace, no empty 8 9 18 282 20 no endspace, no empty 5 9 19 302 30 no endspace, no empty 6 9 20 332 4 allways zero 2 9 21 336 4 allways zero 2 9 22 340 1 3 9 23 341 8 table-lockup 9 0 24 349 8 table-lockup 10 0 25 357 8 allways zero 2 9 26 365 2 2 9 27 367 2 no zeros, zerofill(1) 2 9 28 369 4 no zeros, zerofill(1) 2 9 29 373 4 table-lockup 11 0 30 377 1 3 9 31 378 2 no zeros, zerofill(1) 2 9 32 380 8 no zeros 2 9 33 388 4 allways zero 2 9 34 392 4 table-lockup 12 0 35 396 4 no zeros, zerofill(1) 13 9 36 400 4 no zeros, zerofill(1) 2 9 37 404 1 2 9 38 405 4 no zeros 2 9 39 409 4 allways zero 2 9 40 413 4 no zeros 2 9 41 417 4 allways zero 2 9 42 421 4 no zeros 2 9 43 425 4 allways zero 2 9 44 429 20 no empty 3 9 45 449 30 no empty 3 9 46 479 1 14 4 47 480 1 14 4 48 481 79 no endspace, no empty 15 9 49 560 79 no empty 2 9 50 639 79 no empty 2 9 51 718 79 no endspace 16 9 52 797 8 no empty 2 9 53 805 1 17 1 54 806 1 3 9 55 807 20 no empty 3 9 56 827 4 no zeros, zerofill(2) 2 9 57 831 4 no zeros, zerofill(1) 2 9 1 2 (http://ww2010.atmos.uiuc.edu/(Gl)/abt/aknw/tech.rxml) * About The Gimp plugin registry (http://gimp.foebud.org/registry/doc/) * Java tool Archiver technical detail (Slightly optimistic about *MySQL* ANSI-92 complicate)2* (http://www.fast-inc.com/Products/Archiver/database.html) * Games Domain Cheats Database (http://www.gamesdomain.com/cheats/usrcheat.phtml) * The "Powered By" Page (Kcilink) (http://www.kcilink.com/poweredby/) * Netcasting (http://www.netcasting.net/index.whtml) * http://homepages.tig.com.au/~mjj/nbltips, NBL (Australian National Basketball League) tipping * NBL (Australian National Basketball League) tipping )2* (http://www.fast-inc.com/Products/Archiver/database.html) 35 10 132 35 11 167 4 12 171 16 13 187 35 14 222 4 15 226 16 16 242 20 17 262 20 18 282 20 19 302 30 20 332 4 21 336 4 22 340 1 23 341 8 24 349 8 25 357 8 26 365 2 27 367 2 28 369 4 29 373 4 30 377 1 31 378 2 32 380 8 33 388 4 34 392 4 35 396 4 36 400 4 37 404 1 38 405 4 39 409 4 40 413 4 41 417 4 42 421 4 43 425 4 44 429 20 45 449 30 46 479 1 47 480 1 48 481 79 49 560 79 50 639 79 51 718 79 52 797 8 53 805 1 54 806 1 55 807 20 56 827 4 57 831 4 Compressing station.ISD: (1192 records) - Calculating statistics normal: 20 empty-space: 16 empty-zero: 12 empty-fill: 11 pre-space: 0 end-space: 12 intervall-fields: 5 zero: 7 Original trees: 57 After join: 17 - Compressing file 87.14% (/my/monty/tmp) ls -l station.* -rw-rw-r-- 1 monty my 127874 Apr 17 19:00 station.ISD -rw-rw-r-- 1 monty my 55296 Apr 17 19:04 station.ISM -rw-rw-r-- 1 monty my 5767 Apr 17 19:00 station.frm (my/monty/tmp) isamchk -dvv station ISAM file: station Isam-version: 2 Creation time: 1996-03-13 10:08:58 Recover time: 1997-04-17 19:04:26 Data records: 1192 Deleted blocks: 0 Datafile: Parts: 1192 Deleted data: 0 Datafilepointer (bytes): 3 Keyfile pointer (bytes): 1 Max datafile length: 16777215 Max keyfile length: 131071 Recordlength: 834 Record format: Compressed table description: Key Start Len Index Type Root Blocksize Rec/key 1 2 4 unique unsigned long 10240 1024 1 2 32 30 multip. text 54272 1024 1 Field Start Length Type Huff tree Bits 1 1 1 constant 1 0 2 2 4 zerofill(1) 2 9 3 6 4 no zeros, zerofill(1) 2 9 4 10 1 3 9 5 11 20 table-lockup 4 0 6 31 1 3 9 7 32 30 no endspace, not_always 5 9 8 62 35 no endspace, not_always, no empty 6 9 9 97 35 no empty 7 9 10 132 35 no endspace, not_always, no empty 6 9 11 167 4 zerofill(1) 2 9 12 171 16 no endspace, not_always, no empty 5 9 13 187 35 no endspace, not_always, no empty 6 9 14 222 4 zerofill(1) 2 9 15 226 16 no endspace, not_always, no empty 5 9 16 242 20 no endspace, not_always 8 9 17 262 20 no endspace, no empty 8 9 18 282 20 no endspace, no empty 5 9 19 302 30 no endspace, no empty 6 9 20 332 4 allways zero 2 9 21 336 4 allways zero 2 9 22 340 1 3 9 23 341 8 table-lockup 9 0 24 349 8 table-lockup 10 0 25 357 8 allways zero 2 9 26 365 2 2 9 27 367 2 no zeros, zerofill(1) 2 9 28 369 4 no zeros, zerofill(1) 2 9 29 373 4 table-lockup 11 0 30 377 1 3 9 31 378 2 no zeros, zerofill(1) 2 9 32 380 8 no zeros 2 9 33 388 4 allways zero 2 9 34 392 4 table-lockup 12 0 35 396 4 no zeros, zerofill(1) 13 9 36 400 4 no zeros, zerofill(1) 2 9 37 404 1 2 9 38 405 4 no zeros 2 9 39 409 4 allways zero 2 9 40 413 4 no zeros 2 9 41 417 4 allways zero 2 9 42 421 4 no zeros 2 9 43 425 4 allways zero 2 9 44 429 20 no empty 3 9 45 449 30 no empty 3 9 46 479 1 14 4 47 480 1 14 4 48 481 79 no endspace, no empty 15 9 49 560 79 no empty 2 9 50 639 79 no empty 2 9 51 718 79 no endspace 16 9 52 797 8 no empty 2 9 53 805 1 17 1 54 806 1 3 9 55 807 20 no empty 3 9 56 827 4 no zeros, zerofill(2) 2 9 57 831 4 no zeros, zerofill(1) 2 9 2 9 40 413 4 no zeros 2 9 41 417 4 allways zero 2 9 42 421 4 no zeros 2 9 43 425 4 allways zero 2 9 44 429 20 no empty 3 9 45 449 30 no empty 3 9 46 479 1 14 4 47 480 1 14 4 48 481 79 no endspace, no empty 15 9 49 560 79 no empty 2 9 50 639 79 no empty 2 9 51 718 79 no endspace 16 9 52 797 8 no empty 2 9 53 805 1 17 1 54 806 1 3 9 55 807 20 no empty 3 9 56 827 4 no zeros, zerofill(2) 2 9 57 831 4 no zeros, zerofill(1) 2 9 1 2 (http://homepages.tig.com.au/~mjj/nbltips) * CGI shop (http://www.cgishop.com/) * Whirlycott: Website Design (http://www.whirlycott.com/) * Museum Tusculanum Press (http://www.mtp.dk) * Centro Siciliano di Documentazione (http://csdgi.historie.ku.dk/biblio) * Quake statistics database (http://caribou.dyn.ml.org:8000) * OpenDebate - Interactive Polls & Open Discussion (http://www.opendebate.com) * Online chemical dissertation server (http://vermeer.organik.uni-erlangen.de/dissertationen/) * FreSch! The Free Scholarship Search Service (http://www.freschinfo.com) * Stockholm Pinball Locator (http://www.nada.kth.se/~staffanu/pinball) * HEK A construction company (http://www.hek.com) * Elsevier Bussines Information (http://www.nbi.nl) * Medicial Links (Using Coldfusion and MySQL) (http://vaccination.medicallink.se/) * Search for jobs & people at JobLink-USA (http://www.joblink-usa.com) * Daily news about Linux in German language (http://www.linux-magazin.de/newsflash/) * Competition Formation Skydiving (http://www.skydive.net/competfs) * E-commerce and internal accounting (http://www.galaxy-net.net/Galaxy-NET Telecommunications) * Denmarks leading business daily newspaper Bшrsen (http://www.borsen.dk/) Send any additions to this list to . Contributed programs ******************** Many users of *MySQL* has contributed *very* useful support tools and addons. Here is a list of what is available at `http://www.tcx.se/Contrib' (Or any mirror). `Db.py' Python module with caching. By . `Old-Versions' Previous versions of things found here that you probably wont be interested in. `00-README' This listing. `Vdb-dflts-2.1.tar.gz' This is a new version of a set of library utilities whose intention is to provide a generic interface to SQL database engines such that your application becomes a 3 tiered application. The advantage is that you can easily switch between and move to other database engines by implementing one file for the new backend without needing to make any changes to your applications. By . `access_to_mysql.txt' Paste this function into an Access module of a database which has the tables you want to export. See also exportsql. By Brian Andrews. `dbf2mysql-1.10d.tar.gz' Convert between .dbf files and MySQL tables. By Maarten Boekhold and Michael Widenius. `delphi-interface.gz' Delphi interface to libmysql.dll, by Blestan Tabakov. `dump2h-1.00.gz' Converter from a mysqldump output to a C header file. By Harry Brueckner `emacs-sql-mode.tar.gz' Raw port of a SQL mode for XEmacs. Supports completion. Original by Peter D. Pezaris and *MySQL* port by David Axmark `exportsql.txt' A script that is similar to the "access_to_mysql.txt". Only this one is fully configurable, has better type conversion (including detection of TIMESTAMP fields), gives out warnings and suggestions while converting, quotes *all* special characters on text and binary data, and so on. And it will also convert to mSQL v1 and v2, and is free of charge for anyone. See `http://www.cynergi.net/prod/exportsql/' for latest version. By Pedro Freire `findres.pl' Find reserved words in tables. By Nem W Schlecht. `handicap.tar.gz' Performance handicapping system for yachts. Uses PHP. By `hylalog-1.0.tgz' Store hylafax outgoing faxes in MySQL database. By Sinisa Milivojevic `importsql.txt' A script that does the exact reverse of 'exportsql.txt'. That is, it imports data from MySQL into an Access database via ODBC. This is very handy when combined with exportSQL, since it lets you use Access for all DB design and administration, and synchronize with your actual MySQL server either way. Free of charge. See `http://www.netdive.com/freebies/importsql/' for any updates. Created by Laurent Bossavit of NetDIVE. `jms130b.zip' JDBC driver for *MySQL*. Also contains command line client and other examples. By Xiaokun Kelvin ZHU and GWE Technologies `twz1jdbcForMysql-0.7.5a-beta.tar.gz' New JDBC driver for *MySQL*. This is a beta release and is actively developed. By Terrence W. Zellers. You can always find the newest driver at `http://www.voicenet.com/~zellert/tjFM' `mod_auth_mysql-2.11.tar.gz' Apache authentication module for *MySQL*. By Zeev Suraski `mod_log_mysql-1.04.tar.gz' *MySQL* logging module for Apache. By Zeev Suraski `mrtg-mysql-1.0.tar.gz' MySQL status plotting with MRTG, by Luuk de Boer . `msqltcl-1.50.tar.gz' Tcl interface for msql. See also mysqltcl.c-patch. By Hakan Soderstrom, `mySQLmodule-0.1.4.tar.gz' Pyton interface for MySQL. By Joseph Skinner () `mypasswd-2.0.tgz' Extra for mod_auth_mysql. This is a little tool which allows to add/change user records storing group and/or password entries in *MySQL* tables. By Harry Brueckner `mysql-c++-0.02.tar.gz' *MySQL* C++ wrapper library. By Roland Haenel `http://sunsite.unc.edu/kevina/mysql++/' *MySQL* C++ API; More than just a wrapper library. By `mysql-passwd.README' `mysql-passwd-1.2.tar.gz' Extra for mod_auth_mysql. This is a two part system for use with mod_auth_mysql. `mysql_watchdog.pl' Monitor *MySQL* Daemon for possible lockups. By Yermo Lamers `mysql-webadmin-1.0a8-rz.tar.gz' A tool written in PHP-FI to administrate *MySQL* databases remotely over the web within a Web-Browser. By Peter Kuppelwieser . Updated by Wim Bonis `mysqladm.tar.gz' *MySQL* Web Database Administration written in perl. By Tim Sailer. `mysqladm-2.tgz' Updated version of mysqladm.tar.gz, by High Tide. `mysqltcl.c-patch' Patch for msqltcl-1.50.tar.gz. `nsapi_auth_mysql.tar' Netscape Web Server API (NSAPI) functions to authenticate (BASIC) users against *MySQL* tables. By Yuan John Jiang `mysqlwinadmn.zip' Win32 GUI (binary only) to administrate a database, by David B. Mansel. `pam_mysql.tgz' This module authenticate user via a pam , using mysql. `pike-mysql-1.4.tar.gz' *MySQL* module for pike. For use with the Roxen web server. `radius-0.3.tar.gz' Patches for radiusd to make it support *MySQL*. By Wim Bonis `sqlscreens-0.3.2.tar.gz' TCL/TK code to generate database screens. By Jean-Francois Dockes. `squile.tar.gz' Module for guile that allows guile to interact with sql databases. By Hal Roberts. `twz1jdbcForMysql-0.5.1-alpha.tar.gz' New java JDBC driver by Terrence W. Zellers `wmtcl.doc' `wmtcl.lex' With this you can write html files with inclusions of TCL code. By `wuftpd-2.4.2b12+mysql_support.tar.gz' Pacthes to add logging to *MySQL* for WU-ftpd. By Zeev Suraski `www-sql-0.5.0.lsm' `www-sql-0.5.0.tar.gz' A CGI program that parses an HTML file containing special tags, parses them and inserts data from a *MySQL* database. `xmysql-1.8.tar.gz' A front end to the *MySQL* database engine. It allows for simple queries and table maintenance, as well as batch queries. By Rick Mehalick `xmysqladmin-0.4.4.tar.gz' A front end to the MySQL database engine. It allows reloads, status check, process control, isamcheck, grant/revoke privileges, creating databases, drop databases, create, alter, browse and drop tables. By Gilbert Therrien Who has helped to make *MySQL*. ******************************* Contributors to the *MySQL* distribution in somewhat random order: Michael (Monty) Widenius Has written the following parts of *MySQL*: * All the main code in `mysqld'. * New functions for the string library. * Most of the mysys library. * The `MISAM' library (A B-tree index file handler with index compression and different record formats). * The heap library. A memory table system with our superior full dynamic hashing. In use since 1981 and published around 1984. * replace (Look into it, it's COOL!). * myodbc, the ODBC driver for Windows95. * Fixing bugs in MIT threads to get it to work for *MySQL*. And also UNIREG A curses based application tool with lot of utilities. * Porting of `mSQL' tools like msqlperl, DBD/DBI and DB2mysql. David Axmark * Coordinator and main writer for the *Reference Manual* including enhancements to `texi2html'. Also automatic website updating from this manual. * autoconf & automake support. * The licensing stuff. * Parts of all the text files. Now days only the `README' is left. The rest ended up in the manual. * Our Mail master. * Lots of testing of new features. * Our in house 'free' software lawyer. * Mailing list maintainer (who never has the time to do it right...) * Our original portability code (more than 10 years old now). Now days only some parts of mysys are left. * Someone for Monty to call in the middle of the night when he just got that new feature to work :-) Kim Aldale Rewriting Monty's and David's attempts at English into English. Allan Larsson (The BOSS at TcX) For all the time he has allowed Monty to spend on this 'maybe useful' tool (*MySQL*). Dedicated user (and bug finder) of UNIREG & *MySQL*. Per Eric Olsson For more or less constructive criticism and real testing of the dynamic record format. David J. Hughes For the effort to make a shareware SQL database. We at TcX started with mSQL but found that it couldn't satisfy our purposes so instead we wrote a SQL interface to our application builder UNIREG. mysqladmin & mysql are programs that were largely influenced by their mSQL counterparts. We have put a lot of effort into making the *MySQL* syntax a superset of mSQL. Much of the API:s ideas are borrowed from mSQL to make it easy to port free mSQL programs to *MySQL*. *MySQL* doesn't contain any code from mSQL. Two files (`client/insert_test.c' and `client/select_test.c') in the distribution are non copyrighted files from the mSQL distribution (Copyrighted David J. Hughes). These are included as a example of the changes that must be done to change from mSQL to *MySQL*. Fred Fish For his excellent C debugging and trace library. Monty has made a number of smaller improvements to the library (speed and additional options). Richard A. O'Keefe For his public domain string library. Henry Spencer For his regex library, used in 'WHERE column REGEXP regexp'. Free Software Foundation From whom we got an excellent compiler (gcc) and for their libc from which I have borrowed strto.c to get some code working in Linux. Also readline for the client. Free Software Foundation & The XEmacs development team For a really great editor/environment used by almost everybody at tcx/detron. Igor Romanenko (igor@frog.kiev.ua) mysqldump (Previously msqldump but ported and enhanced by Monty) Tim Bunce, Alligator Descartes For the DBD (perl) interface. Andreas Koenig For the perl interface to *MySQL* Eugene Chan For porting PHP to *MySQL*. Michael J. Miller Jr. For the growing *MySQL* user manual. And a lot of spelling/language fixes for the FAQ. Giovanni Maruzzelli For porting iODBC (unix ODBC). Chris Provenzano Portable user level pthreads. From the copyright: This product includes software developed by Chris Provenzano, the University of California, Berkeley, and contributors. We are currently using version 1_60_beta6 patched by Monty (se mit-pthreads/Changes-mysql). Xavier Leroy The author of LinuxThreads (used by *MySQL* on Linux). Zarko Mocnik Sorting for Slovenian language and the cset.tgz module for easier adding of other character sets. "TAMITO" The _MB character sets macros and ujis and sjis character sets. Yves Carlier mysqlaccess ; A program to show how the access right for a user. Rhys Jones (And GWE Technologies Limited) For the JDBC; A module to extract data from *MySQL* with a Java client. Dr Xiaokun Kelvin ZHU Futher development of the JDBC driver and other *MySQL* related Java tools. James Cooper For setting up a searchable mailing list archive at his site. Rick_Mehalick For xmysql a graphical X client for *MySQL*. Doug Sisk For providing RPM packages of *MySQL* for RedHat Linux. "Diemand Alexander V." For providing RPM packages of *MySQL* for RedHat Linux/Alpha. Antoni Pamies Olive For providing RPM versions of a lot of *MySQL* clients for Intel and Sparc. Jay Bloodworth For providing RPM versions for *MySQL* 3.21 versions. Jochen Wiedmann Maintaining of the perl module DBD::mysql Therrien Gilbert , Jean-Marc Pouyot French error messages. Petr snajdr, Czech error messages. Jaroslaw Lewandowski Polish error messages Miguel Angel Fernandez Roiz Spanish error messages Roy-Magne Mo Norwegian error messages and testing of 3.21.# Timur I. Bakeyev Russian error messages brenno@dewinter.com Italian error messages David Sacerdote Ideas for secure checking of DNS hostnames Gianmassimo Vigazzola" or Port to Win32/NT. Irena Pancirov Win32 port with Borland compiler. Wei-Jou Chen Some support for Chinese(BIG5) characters. Zeev Suraski from_unixtime time formating, ENCRYPT() functions, and bison adviser. Active mailing list member. Luuk de Boer Ported (and extended) the benchmark suite to DBI/DBD. Some new date functions. Jay Flaherty Big parts of the perl DBI/DBD section in the manual. Paul Southworth , Ray Loyzaga Proof-reading of the reference manual. Alexis Mikhailov User definable functions (UDF); CREATE FUNCTION and DROP FUNCTION. Ross Wakelin Help to set up InstallShield for MySQL-win32. Jethro Wright III libmysql.dll James Pereria Mysqlmanager; A Win32 gui tool for administrating MySQL. Curt Sampson Porting of mit-pthreads to NetBSD/Alpha and NetBSD 1.3/i386. Other contributors, bugfinders and testers: James H. Thompson, Maurizio Menghini, Wojciech Tryc, Luca Berra, Zarko Mocnik, Wim Bonis, Elmar Haneke, jehamby@lightside, psmith@BayNetworks.COM, duane@connect.com.au, "Ted Deppner , Mike Simons, Jaakko Hyvдtti. And lots of bug report/patches from the folks on the mailing list. And a big tribute to those that helps us answer question on the mysql@tcx.se mailing list. "Daniel Koch" IRIX setup. "Luuk de Boer" Benchmark questions. Tim Sailer DBD-mysql questions. "Boyd Lynn Gerber (801) 250-O795 Work" SCO related questions. "Mehalick RE (Richard) at MSXSEPC" XmySQL releated questions and basic installation questions. Zeev Suraski Apache module configuration questions (log & auth), PHP related questions, SQL syntax related questions and other general questions. Francesc Guasch General questions Jonathan J Smith Questions pertaining to OS specifics with Linux, SQL syntax, and other things that might be needing some work. David Sklar Using *MySQL* from PHP and Perl. Alistair MacDonald Not yet specified, but is flexible and can handle Linux and maybe HP/UX. Will try to get user to use mysqlbug. John Lyon Questions about installing *MySQL* on Linux systems, using either .rpms, or compiling from source. "Lorvid Ltd." lorvid@WOLFENET.com Simple billing/license/support/copyright issues. Patrick Sherrill ODBC and VisualC++ interface questions. Randy Harmon DBD, Linux, Some SQL syntax questions. *MySQL* change history ********************** Changes in release 3.21.x ========================= Changes in release 3.21.30 -------------------------- * 'mysql' now returns a exit code > 0 if the query returned an error. * Save of command line history to file in mysql client. by Tommy Larsen * Fixed problem with empty lines that was ignored in mysql.cc * Save the pid of the signal handler thread in the pid file instead of the pid of the main thread. * Added patch by tommy@valley.ne.jp to support Japanese characters SJIS and UJIS. * Changed safe_mysqld to redirect startup messages to 'hostname'.err instead of 'hostname'.log to reclaim file space on 'mysqladmin refresh' * enum() had always the first entry as default value. * ALTER TABLE wrote two entires to the update log. * sql_acc() now closes the mysql privilige tables after a reload to save table space and memory. * Changed LOAD DATA to use less memory with tables and blobs. * Sorting on a function which made a division / 0 produced a wrong set in some cases. * Fixed select problem with LEFT() when using the czech character set. * Fixed problem in isamchk; It couldn't repair a packed table in a very unusual case. * Selects with & or | (bit functions) failed on columns with NULL values. * When comparing a field = field, where one of the fields was a part key, only the length of the part key was compared. Changes in release 3.21.29 -------------------------- * LOCK TABLES + 'DELETE from table' never removed locks properly. * Fixed problem when grouping on a OR function. * Fixed permission problem with umask() and creating new databases. * Fixed permission problem on result file with SELECT ... INTO OUTFILE... * Fixed problem in range optimizer (core dump) for a very complex query. * Fixed problem when using MIN(integer) or MAX(integer) in GROUP BY. * Fixed bug on Alpha when using integer keys. (Other keys worked on Alpha). * Fixed bug in WEEK("XXXX-xx-01"). Changes in release 3.21.28 -------------------------- * Fixed socket permission (clients couldn't connect to unix socket on Linux). * Fixed bug in record caches; One could get 'Error from table handler: #' on some OS from some queries. Changes in release 3.21.27 -------------------------- * Added user level locks: GET_LOCK(string,timeout), RELEASE_LOCK(string) * Added opened_tables to 'show status'. * Changed connect timeout to 3 seconds to make it somewhat harder for crackers to kill mysqld trough telnet + TCP/IP. * Fixed bug in range optimizer when using: WHERE key_part_1 >= something and key_part_2 <= something_else * Changed configure for detection of FreeBSD 3.0 9803xx and above * WHERE with string-column-key = constant-string didn't always find all rows if the column had many values differing only with characters of the same sort value (like e and й). * Strings keys looked up with 'ref' was not compared case sensitively. * Added umask() to make log_files non-readable for normal users. * Ignore users with old password (8 byte) on startup if not using -old-protocol. * select which matched all key fields returned the values in the same case as the matched values instead of the found values. (Minor problem) Changes in release 3.21.26 -------------------------- * from_days(0) now returns "0000-00-00" * In DATE_FORMAT() PM and AM was swapped for hours 00 and 12. * Extended the default max key size to 256. * Fixed bug when using BLOB/TEXT in GROUP BY with many tables. * A enum field that is not declared NOT NULL has NULL as default value. (Before the default value was the first enum option) * Fixed bug in the join optimizer code when using many part keys on the same key: INDEX (Organisation,Surname(35),Initials(35)). * Added some tests to the table order optimizer to get some cases with 'SELECT ... FROM many_tables' much faster. * Added a retry loop around accept() to possible fix some problems on some Linux machines. Changes in release 3.21.25 -------------------------- * Changed typedef 'string' to 'my_string' for better portability. * One can now kill threads that are waiting for 'disk full'. * Fixed some problems with UDF functions. * Added long options for isamchk. Try isamchk -help. * Fixed a bug when using 8 bytes long (alpha); filesort() didn't work. Affects DISTINCT, ORDER BY and GROUP BY on 64 bit processors. Changes in release 3.21.24 -------------------------- * Dynamic loadable functions. Based on source from Alexis Mikhailov. * One couldn't delete from a table if no one had done a select on the table. * Fixed problem with range optimizer which many OR's on key parts inside each other. * Recoded min() and max() to work properly with strings and HAVING. * Changed default umask for new files from 0664 to 0660. * Fixed problem with LEFT JOIN and constant expressions in the ON part. * Added Italian error messages from * configure now works better on OSF1 (tested on 4.0D). * Added hooks to allow LIKE optimization with international character support. * Upgraded DBI to 0.93 Changes in release 3.21.23 -------------------------- * Fixed that the following symbols are not reserved words: TIME DATE TIMESTAMP TEXT BIT ENUM NO ACTION CHECK YEAR MONTH DAY HOUR MINUTE SECOND STATUS VARIABLES. * Setting a TIMSTAMP to NULL in LOAD DATA INFILE... didn't set the current time for the TIMESTAMP. * Fix that BETWEEN recognizes binary strings. Now BETWEEN is case sensitive. * Added switch -skip-thread-priority for systems where mysqld's thread scheduling doesn't work properly (BSDI 3.1). * Added ODBC functions DAYNAME() and MONTHNAME(). * Added function TIME_FORMAT(). This works like DATE_FORMAT() but takes a time string (HH:MM:DD) as argument. * Fixed unlikely(?) key optimizer bug when using ORs of key parts inside ANDs. * Added command 'variables' to mysqladmin. * A lot of small changes to the binary releases. * Fixed a bug in the new protocol from MySQL 3.21.20. * Changed ALTER TABLE to work with WIN32 (Win32 can't rename open files). Fixed also a couple of small bugs in the WIN32 version. * All standard MySQL clients are now ported to MySQL-win32. * MySQL can now be started as a service on NT. Changes in release 3.21.22 -------------------------- * Starting with this version all MySQL distributions will be configured, compiled and tested with crash-me and the benchmarks on the following platforms: SunOS 5.6 sun4u, SunOS 5.5.1 sun4u, SunOS 4.14 sun4c, SunOS 5.6 i86pc, IRIX 6.3 mips5k, HP-UX 10.20 hppa, AIX 4.2.1 ppc, OSF1 V4.0 alpha, FreeBSD 2.2.2 i86pc and BSDI 3.1 i386. * Fix of count(*) problems when the WHERE clause didn't match any records. (Bug from 3.21.17) * Removed that NULL = NULL is true. Now one must use IS NULL or IS NOT NULL to test if a value is NULL. (This is according to ANSI SQL but may break old applications that are ported from mSQL) One can get the old behaviour by compiling with -DmSQL_COMPLIANT * Fixed bug that core dumped when using many LEFT OUTER JOIN's. * Fixed bug in ORDER BY on string formula with possible NULL values. * Fixed problem in range optimizer when <= on sub index. * Added functions DAYOFYEAR(), DAYOFMONTH(), MONTH(), YEAR(), WEEK(), QUARTER(), HOUR(), MINUTE(), SECOND() and FIND_IN_SET(). * Added command SHOW VARIABLES. * Added support of 'long constant strings' from ANSI SQL: select 'first ' 'second'; -> 'first second'; * Upgraded mSQL-Mysql-modules to 1.1825 * Upgraded mysqlaccess to 2.02 * Fixed problem with Russian character set and LIKE. * Ported to openbsd 2.1 * New Dutch error messages Changes in release 3.21.21a --------------------------- * Configure changes for some OS. Changes in release 3.21.21 -------------------------- * Fixed optimizer bug when using 'WHERE data_field=date_field2 and date_field2=constant' * Added command 'show status' * Removed manual.ps from the source distribution to make it smaller. Changes in release 3.21.20 -------------------------- * Changed maximum table name and column name lengths from 32 to 64. * Aliases can now be of 'any' length. * Fixed that 'mysqladmin stat' returns right number of queries. * Changed protocol (downward compatible) to mark if a column is auto_increment or a timestamp. This is needed for the new Java driver. * Added hebrew sorting order by Zeev Suraski. * Solaris 2.6: Fixed configure bugs and increased maximum table size from 2G to 4G Changes in release 3.21.19 -------------------------- * Upgraded DBD to 1823. This version implements mysql_use_result in DBD-Mysql. * Benchmarks updated for empress (by Luuk) * Fixed a case of slow range searching. * Configure fixes (Docs directory). * Added function `REVERSE()' (by Zeev Suraski) Changes in release 3.21.18 -------------------------- * Give error message if client C functions are called in wrong order. * Added automatic reconnect to the libmysql.c library. If a write command fails a automatic reconnect is done. * Small sort sets doesn't use temporary files anymore. * Upgraded DBI to 0.91 * Fixed a couple of problems with LEFT OUTER JOIN. * Added CROSS JOIN syntax. CROSS is now a reserved word. * Recoded yacc/bison stack allocation to be even safer and allow *MySQL* to handle even bigger expressions. * Fixed a couple of problems with the update log. * ORDER BY was slow when used with key ranges. Changes in release 3.21.17 -------------------------- * Changed documentation string of -with-unix-socket-path to avoid confusion. * Added ODBC and ANSI SQL style `LEFT OUTER JOIN'. * The following are new reserved words: `LEFT', `NATURAL', `USING' * The client library is now using the environment variable `MYSQL_HOST' as the default host if it's defined. * `SELECT column, SUM(expr)' now returns `NULL' for column when there are matching rows. * Fixed problem with compare of binary strings and blobs with ASCII characters over 127. * Fixed lock problem: When freeing a read lock on a table with multiple read locks, a thread waiting for write lock would have given the lock. This shouldn't affect data integrity, but could possible make mysqld to restart if one thread was reading data that another thread modified. * LIMIT offset,count didn't work in INSERT ... SELECT. * Optimized key block caching. This will be quicker than the old one when using bigger key caches. Changes in release 3.21.16 -------------------------- * Added ODBC 2.0 & 3.0 functions: `POWER()', `SPACE()', `COT()', `DEGREES()', `RADIANS()', `ROUND(2 arg)' and `TRUNCATE()'. * *WARNING INCOMPATIBLE CHANGE!!*. `LOCATE()' parameters where swapped according to ODBC standard. Fixed. * Added function `TIME_TO_SEC()'. * In some cases default values was not used for `NOT NULL' fields. * Timestamp wasn't updated in `UPDATE SET ...' if the timestamp was used as. * Allow empty strings as default values for `BLOB' and `TEXT' to be compatible with mysqldump. Changes in release 3.21.15 -------------------------- * *WARNING INCOMPATIBLE CHANGE!!* mysqlperl is now from Msql-Mysql-modules. This means that the connect() now takes host,database,user,password ! The old version took host,database,password,user. * Allow `DATE '1997-01-01'', `TIME '12:10:10'' and `TIMESTAMP '1997-01-01 12:10:10'' formats required by ANSI SQL. *WARNING INCOMPATIBLE CHANGE!!* This has the unfortunate side-effect that one can't have columns named `DATE', `TIME' or `TIMESTAMP' anymore :( Old columns can only be accessed with 'tablename.columnname'! * Changed Makefiles to hopefully work better with BSD systems. Also manual.dvi is now included in the distribution to avoid having stupid makes trying to rebuild it. * Readline library upgraded to version 2.1 * A new sortorder german-1. That is a normal iso-latin1 with a german sort order. * Perl DBI/DBD is now included in the distribution. DBI is now the recommended way to connect to *MySQL* from perl. * New portable benchmark suite with DBD, with test results from mSQL 2.0.3, *MySQL*, PostgreSQL 6.2.1 and Solid server 2.2. * crash-me is now included with the benchmarks; This is a perl program designed to find as many limits as possible in a SQL server. Tested with mSQL, postgreSQL, Solid and *MySQL*. * Fixed bug in range-optimiser that crashed mysql on some queries. * Table and column name completion for mysql command line tool, by Zeev Suraski and Andi Gutmans. * Added new command `REPLACE', which works like `INSERT' but replaces conflicting records with the new record. `REPLACE INTO TABLE ... SELECT ...' works also. * Added new commands: `CREATE DATABASE db_name' and `DROP DATABASE db_name'. * Added `RENAME' option to `ALTER TABLE': `ALTER TABLE name RENAME AS new_name'. * make_binary_distribution now includes libgcc.a in libmysqlclient.a. This should make linking work for people without gcc. * Changed `net_write()' to `my_net_write()' because of name conflict with sybase. * New function `DAYOFWEEK()' compatible with ODBC. * Stack checking and bison memory overrun checking to get *MySQL* safer with weird queries. Changes in release 3.21.14b --------------------------- * Fixed a couple of small configure problems on some platforms. Changes in release 3.21.14a --------------------------- * Ported to SCO Openserver 5.0.4 with FSU-threads. * HP/UX 10.20 should work. * Added new functions DATE_FORMAT() and DATE_ADD_MM().. * Added NOT IN. * Added automatic removal of 'ODBC function conversions': {fn now() } * Handle ODBC 2.50.3 option flags. * Fixed compare of DATE and TIME with NULL. * Changed language name from germany to german to be consistent with the other language names. * Fixed sorting problem on functions returning a float. Before the values was converted to a int before sorting. * Fixed slow sorting when sorting on key field when using KEY_COLUMN=constant. * SORTING on calculated DOUBLE values sorted on integer results instead. * 'mysql' doesn't need a database argument anymore. * Changed the place where HAVING should be. According to ANSI it should be after GROUP BY but before ORDER BY. *MySQL* 3.20 had it wrongly last. * Added Sybase command: USE DATABASE to start using another database. * Added automatic adjusting of number of connections and table cache size if the maximum number of files that can be opened are less than needed. This should fix that mysqld doesn't crash even if one hasn't done a ulimit -n 256 before starting mysqld. * Added lots of limit checks to make it safer when running with too little memory or when doing weird queries. Changes in release 3.21.13 -------------------------- * Added retry of interrupted reads and clearing of errno. This makes Linux systems much safer! * Fixed locking bug when using many alias on the same table in the same select. * Fixed bug with LIKE on number key. * New error message so one can check if the connection was lost while the command was running or if the connection was down from the start. * Added -table option to mysql to print in table format. Moved time and row information after query result. Added automatic reconnect of lost connections. * Added != as an alias for <>. * Added function VERSION() to make easier logs. * New multi-user test 'tests/fork_test.pl' to put some strain on the thread library. Changes in release 3.21.12 -------------------------- * Fixed ftruncate() call in MIT-threads. This made isamchk() destroy the .ISM files on (Free)BSD systems 2.# * Fixed broken __P_ patch in MIT-threads * Many memory overrun checks. All string functions now return `NULL' if the returned string should be longer than `max_allowed_packet'. * Changed the name if the `INTERVAL' type to `ENUM', because `INTERVAL' is used in ANSI SQL. * In some cases doing a JOIN + GROUP + INTO OUTFILE, the result wasn't grouped. * LIKE with '_' as last character didn't work. Fixed * Added extended ANSI SQL `TRIM()' function. * Added `CURTIME()'. * Added `ENCRYPT()' function by Zeev Suraski. * Fixed better `FOREIGN KEY' syntax skipping. New reserved words: `MATCH', `FULL', `PARTIAL' * mysqld now allows ip and hostname to the `--bind-address' option. * Added "SET OPTION CHARACTER SET cp1251_koi8" to enable conversions off data to/from cp1251_koi8. * Lots of changes for Win95 port. In theory this version should now be easily portable to Win95. * Changed the create column syntax off `NOT NULL' to be after the `DEFAULT' value as specified in the ANSI SQL standard. This will make mysqldump with `NOT NULL' and default values incompatible with *MySQL* 3.20. * Added a lot of function name alias so one can use the functions with ODBC or ANSI SQL92 syntax. * Fixed `ALTER TABLE person ALTER COLUMN phone SET DEFAULT NULL' syntax. * Added CHAR and BIT as a synonyms for CHAR(1) * Fixed core dump when updating as user with only select privilege. * INSERT ... SELECT ... GROUP BY didn't work in some cases. On got 'Invalid use of group function' * When using LIMIT, SELECT now always uses keys instead of record scan. This will give better performance on SELECT and a WHERE that matches many rows. * Added Russian error messages. * In some cases doing a join + group + INTO OUTFILE, the result wasn't grouped. Changes in release 3.21.11 -------------------------- * Configure changes. * MySQL new works with the new thread library on BSD/OS 3.0. * Added new group functions: BIT_OR() and BIT_AND(). * Added compatibility functions: CHECK, REFERENCES. CHECK is now a reserved word. * Added BIT as a synonym for CHAR(1) to get better compatibility. * Added option ALL to GRANT for better compatibility. (GRANT is still a dummy fuction. * Added partly translated dutch messages. * Fixed bug in ORDER BY and GROUP BY with NULL columns * Added function last_insert_id() to retreive last auto_increment value. This is for clients to ODBC that can't use the mysql_insert_id API function, but can be used by any client. * Added option '-flush-logs' to mysqladmin. * Added command 'status' to mysql. * Fixed problem with order/group by because of bug in gcc. * Fixed problem with INSERT ... SELECT .. GROUP BY. Changes in release 3.21.10 -------------------------- * New mysqlaccess. * CREATE supports now all ODBC types and the mSQL `TEXT' type. All ODBC 2.5 functions is also supported (added REPAT). This gives better portability. * Added text types: `TINYTEXT', `TEXT', `MIDDLETEXT' and `LONGTEXT'. These are actually blobs, but all searching is done case independent. * All old `BLOB' fields are now `TEXT' fields. This only changes that all searching on strings are case independent. One have to do a ALTER TABLE and change the field to BLOB if one wants to have tests done case dependent. * Fixed some configure issues. * Made the locking code a bit safer. Fixed very unlikely dead lock situation. * Fixed a couple of bugs in the range optimiser. Now the new range benchmark test-select works. Changes in release 3.21.9 ------------------------- * Added -enable-unix-socket=pathname arg to configure. * Fixed a couple of portable problems with include files. * Fixed bug in range calculation that could return empty set when searching on multiple key with only one entry (very rare). * Most things ported to FSU threads, which should allow *MySQL* to run on SCO. *Note SCO::. Changes in release 3.21.8 ------------------------- * Works now in Solaris 2.6 * Added handling of calculation of sum() functions. One can now use for example: SUM(column)/COUNT(column) * Added handling of trigometric functions: PI(), ACOS(), ASIN(), ATAN(), COS(), SIN() and TAN(). * New languages: norwegian, norwegian-ny and portuguese. * Fixed parameter bug in net_print in procedure.cc. * Fixed a cople of memory leaks. * Now allow also the old SELECT ... INTO OUTFILE syntax. * Fixed bug with group by and select on key with many values. * mysql_fetch_lengths() returned sometimes wrong lengths when one used mysql_use_result(). This affected at least some cases of mysqldump -quick. * Allow TIME, DATE and TIMESTAMP as column names. * Fixed bug in optimisation of WHERE const op field. * Fixed problem when sorting on NULL fields. * Fixed a couple of 64bit (Alpha) problems * Added option -pid-file=# to mysqld * Added date formating to from_unixtime(), originally by Zeev Suraski. * Fixed bug in BETWEEN in range optimiser (Did only test = of the first argument). * Added machine dependent files for mit-pthreads i386-SCO. There is probably more to do to get this to work on SCO 3.5. Changes in release 3.21.7 ------------------------- * Changed to Makefile.am to take advantage of automake 1.2. * Added the beginnings of a benchmark suite. * Added more secure password handling. * Added new client function: mysql_errno() to get the error number of the error message. This makes error checking in the client much easier. This makes the new server incompatible with the 3.20.# server when running without -old-protocol. The client code is backward compatible. More information can be found in the README file! * Fixed some problems when using very long, illegal names. Changes in release 3.21.6 ------------------------- * Fixed more portability issues (wrong sigwait and sigset define) * configure should now be able to detect the last argument to accept(). Changes in release 3.21.5 ------------------------- * Should now work at FreeBSD 3.0, if one used the FreeBSD-3.0-libc_r-1.0.diff which can be found at `http://www.tcx.se/Download/Patches' * Added new option to mysqld: -O tmp_table_size=# * New function from_unixtime(timestamp) which returns a date string in YYYY-MM-DD HH:MM:DD format. * New function sec_to_time(seconds) which returns a string in H:MM:SS format. * new function: substring_index(), originally by Zeev Suraski. Changes in release 3.21.4 ------------------------- * Should now configure and compile on OSF1 4.0 with the Dec compiler. * configure and compile on BSD/OS 3.0 works, but due to some bugs in BSD/OS 3.0, mysqld doesn't work on it yet. * configure and compile on FreeBSD 3.0, but I couldn't get pthread_create to work. Changes in release 3.21.3 ------------------------- * Added reverse check lookup of hostnames to get better security. * Fixed some possible buffer overflows if one uses too long filenames. * mysqld doesn't accept hostnames that starts with digits followed by a '.' because the hostname may look like a IP. * Added option -skip-networking to only allow socket connections. (This will not work with MIT threads!) * Added check of too long table names for alias. * Added check if database name is okey. * Addded check if too long table names. * Removed wrong free() that killed the server on 'create/drop database'. * Changed the name of some mysqld -O options to better names. * Added option '-O join_cache_size=#'. * Added option '-O max_join_size=#' to be able to set a limit how big queries (in this case big = slow) one should be able to handle without specifying 'SQL_OPTION OPTION_BIG_SELECTS=1'. A # = is about 10 examined records. The default is 'unlimited'. * When comparing a TIME, DATE, DATETIME or TIMESTAMP column to a constant the constant is converted to a time value before comparing. This will make it easier to get ODBC and particularly Access97 to work with the above types. It should also make dates easier to use and the compares should be quicker than before. * Applied patch from Jochen Wiedmann that fixes that query() in mysqlperl now can take queries with \0 in it. * Store of timestamp with 2 digit year YYMMDD didn't work. * Fix that timestamp isn't automaticly updated if set in a update clause. * Now the automatic timestamp field is the FIRST timestamp field. * SELECT * INTO OUTFILE, which didn't correctly if the outfile already existed. * 'mysql' now shows thread id when starting or doing a reconnect. * Changed the default sort buffer size from 2M to 1M. Changes in release 3.21.2 ------------------------- * The range optimiser is cooded, but only 85% tested. It can be enabled with -new, but it crashes core a lot yet... * More portable. Should compile one AIX and alpha-digital. At least the isam library should be relative 64 bit clean. * New isamchk which can detect and fix more problems. * New options for isamlog. * Using new version of automake * Many small portability changes (from the AIX and alpha-digital port) Better checking of pthread(s) library. * czech error messages by snajdr@pvt.net * 'mysql' now shows thread id when starting or doing a reconnect. * Decresed some buffers to get less problems on system with little memory. Also added more checks to handle 'out of memory' problems * mysqladmin: One can now do 'mysqladmin kill 5,6,7,8' * When the max connection limit is reached, one extra connection by a user with the PROCESS_ACL privilege is granted. * Added new mysqld option: -O backlog=# * Increased max packet size from 512K to 1024K for client. * Almost all of the functions code is now tested in the intern test suite. * ALTER TABLE now returns warnings from field conversions. * Port changed to 3306 (got it reserved from ISI). * Added a fix for Visual Fox Base so that any schema name from a table specification is automaticly removed. * New function ASCII. * Removed the between() function. On should use the 'col BETWEEN a AND b' syntax instead. * MySQL now doesn't anymore have to use a extra temporary table when sorting on functions or SUM functions. * Fixed bug that one couldn't use 'table_name.field_name' in UPDATE. * Fixed SELECT DISTINCT when using 'hidden group'. For example: SELECT DISTINCT MOD(some_field,10) FROM test GROUP BY some_field; Note: some_field is normally in the select part. ANSI SQL should require it. Changes in release 3.21.0 ------------------------- * New keywords used: INTERVAL, EXPLAIN, READ, WRITE, BINARY * Added ODBC functions CHAR(num,...) and ASCII(string). * Removed function BETWEEN(a,b,c). One should use the standard ANSI SYNTAX: expr BETWEEN expr AND expr. * New operator IN. This uses a binary search to find a match. * New command `LOCK TABLES table_name [AS alias] (READ | WRITE), ...' * New server option `mysqld --log-update' to get a log suitable for incremental updates * new command: EXPLAIN SELECT ... to get info about how the optimzier will do the join. * For easier client code, the client shouldn't anymore use `FIELD_TYPE_TINY_BLOB', `FIELD_TYPE_MEDIUM_BLOB', `FIELD_TYPE_LONG_BLOB' or `FIELD_TYPE_VAR_STRING' (as previously returned by mysql_list_fields). One should instead only use `FIELD_TYPE_BLOB' or `FIELD_TYPE_STRING'. If one wants exact types one should use the command `SHOW FIELDS' . * Added varbinary syntax: `0x######' which can be used as a string (default) or a number. * `FIELD_TYPE_CHAR' is renamed to `FIELD_TYPE_TINY'. * Changed all fields to C++ classes. * Removed FORM struct. * A field with a `DEFAULT' doesn't have to be `NOT NULL' anymore. * New field types: `INTERVAL' A string with only can take a couple of defined values. The value is stored as a 1-3 byte number that automaticly is mapped to a string. This is sorted according to string positions! `SET' A string with may have one or many string values separated with ','. The string is stored as a 1,2,3,4 or 8 byte number where each bit stands for a specific string. This is sorted according to unsigned value of the stored packed number. * Now all function calculation is done with double or long long. This will give one the full 64 bits range with bit functions and fix some conversions that previously could give precision losses. One should avoid using 'unsigned long long' columns with full 64 bits range (numbers bigger than 9223372036854775807) because calculations is done with signed long long. * ORDER BY will now put NULL fields first. GROUP BY will also work with NULL. * Full WHERE with expressions. * New range optimiser with can resolve ranges when some prefix keypart is constant. Example: SELECT * FROM table_name WHERE key_part_1="customer" and key_part_2 >= 10 AND key_part_2 <= 10) Changes in release 3.20.x ========================= Changes from 3.20.18 to 3.20.32b are not documented here since the the 3.21 release bransched here. And the relevant changes are also documented as changes to the 3.21 version. Changes in release 3.20.18 -------------------------- * Added -p# (remove # directories from path) to isamlog. All files are written with a relative path from the database directory Now mysqld shouldn't crash on shutdown when using -log-isam. * New mysqlperl version. Is now compatible with msqlperl-0.63. * New DBD module available in Contrib/ * Added group function STD() (standard derivation). * The mysql server is now by default compiled without debugging information. This will make the daemon smaller and faster. * Now one usually only have to give -basedir to mysqld. All other paths are relative in a normal installation. * BLOBs contained sometimes garbage when used with a SELECT on more than one table and ORDER BY. * Fixed that calculations that are not in GROUP BY works as expected. (ANSI SQL extension) Example: SELECT id,id+1 FROM table GROUP BY id * The test of using MYSQL_PWD was reversed. Now MYSQL_PWD is enabled as default in the default release. * Fixed convert bug which got mysqld to core dump with Aritmetic error on Sparc-386 * Added option -unbuffered to mysql. (For new mysqlaccess) * When using overlapping (unnecessary keys) and join over many tables the optimiser could get confused and return 0 records. Changes in release 3.20.17 -------------------------- * One can now use BLOBs columns and the functions IS NULL and IS NOT NULL in the WHERE clause. * All communication packages and row buffers are now alloced dynamicly on demand. The default `max_allowed_packet' is now 65K for the server and 512K for the client. This is mainly used to catch wrong packets that could trash all memory. The server limit may be changed when it is started. * Changed stack usage to use less memory. * Changed safe_mysqld to check for running daemon. * The `ELT()' function is renamed to `FIELD()'. The new `ELT()' function returns a value based on an index: `FIELD()' is the invers of `ELT()' Example: `ELT(2,"A","B","C")' returns `"B"'. `FIELD("B","A","B","C")' returns `2'; * COUNT(field) where field could have a NULL value now works. * A couple of bug fixed in SELECT .. GROUP BY. * Fixed memory overrun bug in WHERE with many unoptimisable brace levels. * Fixed some small bugs in the grant code. * If hostname isn't found by get_hostname, only the IP is checked. Before one one got 'Access denies' * Inserts of timestamps with values didn't always work. * INSERT INTO ... SELECT .. WHERE could give the error 'Dupplicated field' * Added some tests to safe_mysqld to make it 'safer' * LIKE was case sensitive in some places and case insensitive in other. Now `LIKE' is always case insensitive. * mysql.cc; Allow '#' anywhere on the line. * New command 'SET OPTION SQL_SELECT_LIMIT=#'. Se the FAQ for more details. * New version of the mysqlaccess script * Change from_days() and weekday() to also take a full timestamp or a datetime as argument. Before they only took a number of type YYYYMMDD or YYMMDD. * Added new function unix_timestamp(timestamp_column); Changes in release 3.20.16 -------------------------- * More changes in MIT threads to get them safer. Fixed also some link bugs at least in SUNOS. * Changed mysqld to go around a bug in MIT threads. This makes multiple small selects 20 times faster. Now lock_test.pl should work. * Added mysql_FetchHash(handle) to mysqlperl * The mysqlbug script is now distributed built to allow for reporting bugs that appear during the build with it. * Changed libmysql.c to prefer to use getpwuid() insted of cuserid(). * Fixed bug in select optimiser when using many tables with the same column used as key to different tables. * mysql.cc; Allow '#' anywhere on the line. * Added new latin2 and Russian KOI8 character tables. * Added support for a dummy GRANT command satisfy Powerbuilder. Changes in release 3.20.15 -------------------------- * Fixed fatal bug 'packets out of order' when using MIT threads. * Removed possible loop when thread waits for command from client and fcntl() fails. Thanks to Mike Bretz for finding this bug * Changed alarm loop in mysqld.cc because shutdown didn't always succeed in Linux. * Removed use of termbits from mysql.cc This conflicted with glibc 2.0 * Fixed some syntax errors for at least BSD and Linux. * Fixed bug when doing a select as superuser without a database. * Fixed bug when doing SELECT with group calculation to outfile. Changes in release 3.20.14 -------------------------- * If one gives '-p' or -password to mysql without an argument, the password will be asked from the tty. * Added default password from MYSQL_PWD. (by Elmar Haneke) * Added commando 'kill' to mysqladmin to kill a specific mysql thread. * Sometimes when doing a reconnect on a down connection this succeeded first on second try. * Fixed adding a auto_increment key with ALTER_TABLE. * AVG() gave too small value on some selects with GROUP BY and ORDER BY. * Added new DATETIME type (by Giovanni Maruzzelli ) * Fixed that define 'DONT_USE_DEFAULT_FIELDS' works * Changed to use a thread to handle alarms instead of signals on Solaris to avoid race conditions. * Fixed default length of signed numbers. (George Harvey ) * Allow anything for CREATE INDEX. * Add prezeros when packing numbers to DATE, TIME and TIMESTAMP. * Fixed a bug in OR of multiple tables (Gave empty set). * Added many patches to MIT threads. This fixes at least one lookup bug. Changes in release 3.20.13 -------------------------- * Added ANSI SQL94 DATE and TIME types. * Fixed bug in select with and-or levels. * Added support for Slovenian characters. The Contrib directory contains source and instructions to add other character sets. * Fixed bug with limit and order by. * Allow order and group on items that isn't in the select list. (Thanks to Wim Bonis for pointing this out) * Allow setting of timestamp values in INSERT. * Fixed bug with SELECT ... WHERE ... = NULL. * Added changes for glibc 2.0. To get glibc to work one should add the gibc-2.0-sigwait-patch before compiling glibc. * Fixed bug in alter table when changeing a not null field to allow NULLs. * Added some ANS92 synonyms as field types to CREATE TABLE. CREATE TABLE now allows FLOAT(4) and FLOAT(8) to mean FLOAT and DOUBLE. * new utility program mysqlaccess by Yves.Carlier@rug.ac.be. This program shows the access rights for a specific user and the grant rows which determinate this grant. * Added WHERE const op field (by bonis@kiss.de) Changes in release 3.20.11 -------------------------- * When using SELECT ... INTO OUTFILE all temporary tables are ISAM instead of HEAP to allow big dumps. * Changed date functions to be 'string functions'. This fixed some 'funny' side effects when sorting on dates. * Extended ALTER TABLE according to SQL92. * Some minor compability changes. * Added -port and -socket to all utility programs and mysqld. * Fixed MIT threads readdir_r(). Now mysqladmin create database and drop database should work. * Changed MIT threads to use our tempnam. This should fix the 'sort aborted' bug. * Added sync of records count in sql_update. This fixed slow updates on first connection. (Thanks to Vaclav Bittner for the test) Changes in release 3.20.10 -------------------------- * New insert type: INSERT INTO ... SELECT ... * mediumblob fixed. * Fixed bug in ALTER TABLE and BLOBs. * SELECT ... INTO OUTFILE now creates the file in the current database directory. * DROP TABLE can now take a list of tables. * Oracle synonym DESCRIBE (DESC) * Changes to make_binary_distribution * Added some comments about conifgures c++ link test to installation instructions. * Added -without-perl to configure. * Lot's of small portability changes. Changes in release 3.20.9 ------------------------- * Alter table didn't copy null bit. This resulted that NULL fields where always NULL. * CREATE didn't take numbers as DEFAULT. * Some compatibility changes for SunOS. * Removed config.cache from old distribution. Changes in release 3.20.8 ------------------------- * Fixed bug with ALTER TABLE and multi part keys. Changes in release 3.20.7 ------------------------- * New commands: ALTER TABLE, SELECT ... INTO OUTFILE and LOAD DATA INFILE. * New functions: NOW() * Added new field: file_priv to mysql/user table. * New scripts 'add_file_priv' which add the new field 'file_priv' to the user table. This scripts must be executed if one wants to use the new SELECT ... INTO and LOAD DATA INFILE... commands with a version of mysql less than 3.20.7. * Fixed bug in locking code, with made lock_test.pl test fail. * new files NEW and BUGS * Changed select_test.c and insert_test.c to include config.h * Added command 'status' to mysqladmin for short logging. * Increased max keys to 16 and max key parts to 15. * Use of sub keys. A key may now be a prefix of a string field. * Added option -k for mysqlshow to get key info for table. * Added long options to mysqldump. Changes in release 3.20.6 ------------------------- * Portable to more systems because of MIT threads. This will automatically be used is configure can not find a -lpthreads library. * GNU style long options to almost all programs. Test with 'program -help'. * Some shared library support for linux. * The FAQ is now in .texi format and is available in .html, .text, .ps, * Added new sql function RAND([init]) * Changed sql_lex to handle \0 unquoted, but the client can't send the query through the C api, because it takes a str pointer. one have to use mysql_real_query() to send the query. * Added API function: mysql_get_client_info * mysqld now uses the N_MAX_KEY_LENGTH from nisam.h as the max allowed key length. * The following now works: "select filter_nr,filter_nr from filter order by filter_nr" Before you got the error: "Column: 'filter_nr' in order clause is ambiguous" * mysql now outputs \0 \t \n and \\ when writing tab separated output. when encountering ascii 0, tab, newline or \. This is to allow printing of binary data in a portable format. To get old behavior use -r (or -raw). * Added german error messages (60 of 80 error messages translated) * Added new api function: mysql_fetch_lengths(MYSQL_RES *) which returns a array of of column lengths (of type uint). * Fixed bug with IS NULL in where clause. * Changed the optimiser a little to get better results when searching on a key part. * Added select option STRAIGHT_JOIN to tell the optimiser that it should join tables in the given order. * Added support of comment starting with '-' in mysql.cc (Postgres syntax) * You can have select_expressions and table columns in a select which are not used in the group part. This makes it efficient to implement lookups. The used column should be a constant for each group because the value is calculated only calculated once for the first found row in a group. SELECT id,lookup.text,sum(*) FROM test,lookup WHERE test.id=lookup.id group by id; * Fixed bug in SUM(function) (Could make core dump) * Changed auto_increment according to SQL_SYNTAX: INSERT into table (auto_field) values (0) inserted 0, but the SQL_SYNTAX stated it should insert a auto_increment value. * mysqlshow.c: Added number of records in table. Had to change the client code a little to fix this. * mysql now allows double " or "" in strings for embedded ' or ". * New math functions: EXP, LOG, SQRT, ROUND, CEILING Changes in release 3.20.3 ------------------------- * The configure source now compiles a thread free client library `-lmysqlclient'. This is the only library that needs to be linked with client applications. When using the binary releases one have to link with `-lmysql -lmysys -ldbug -lstrings' as before. * New readline from bash-2.0. * LOTS of small changes to configure and makefiles (and related source). * There should now be possible to compile in another directory using vpath. Tested with GNU Make 3.75. * safe_mysqld and mysql.server changed to be more compatible between the source and the binary releases. * LIMIT takes now one or two numerical arguments. If one argument the argument indicates the maximum number of rows in a result. If two arguments the first arguments says the offset to the first row to return, the second is the maximum number of rows. With this it's easy to do a poor mans next page/previous page www application. * Changed name of SQL function FIELDS to ELT. Changed sql function INTERVALL() to INTERVAL(). * Made SHOW COLUMNS a synonym for SHOW FIELDS. Added compatibility syntax FRIEND KEY to create table. This creates in mysql a non unique key on the given columns. * Added CREATE INDEX and DROP INDEX as compatibility functions. In mysql CREATE INDEX only checks if the index exists and gives an error if it doesn't exists. DROP INDEX always succeeds. * mysqladmin.c: Added client version to version info. * Fixed core dump bug in sql_acl (core on new connection). * Removed host,user and db tables from database test in the distribution. * FIELD_TYPE_CHAR can now be signed (-128 - 127) or unsigned (0 - 255) Before it was always unsigned. * Bug fixes in concat(), weekday() * Changed a lot of source to get mysqld to be compiled with SUNPRO compiler. * SQL functions must now have a '(' directly after the function name. user '(' is now regarded as an identifier and a '(' Changes in release 3.20.0 ------------------------- * The source distribution is done with configure and automake: It will make porting much easier. Readline is included in the distribution. * Separate client compilation: The client code should be very easy to compile on system which doesn't have threads. * The old perl interface code is automaticly compiled and installed. Automatic compiling of DBD will follow when the new DBD code is ported. * Dynamic language support: mysqld can now be started with Swedish or English (default) error messages. * new functions: INSERT(),RTRIM(),LTRIM() and FORMAT(). * mysqldump now works correctly for all field types (even auto_increment). The format for 'show fields from table' is changed so the 'type' column contains info suitable for 'CREATE TABLE'. In previous releases some CREATE TABLE info had to be patched to when recreating tables * Some parser bugs from 3.19.5 (blob and timestamp) are corrected. Timestamp now returns different date info depending of it's create length. * Changed parser to allow a database name, table name and field name to start with a number or '_'. * All old C code from UNIREG changed to c++ and cleaned up. This makes the daemon a little smaller and easier to understand. * A lot of small bug fixes done. * New INSTALL files (not final version) and some info regarding porting. Changes in release 3.19.x ========================= Changes in release 3.19.5 ------------------------- * Some new functions, some more optimisation on joins. * Should now compile clean on Linux (2.0.x) * Added functions DATABASE(),USER(),POW(),LOG10() (needed for ODBC). * In a WHERE with a ORDER BY on fields from only one table the table is now preferred as first table in a multi-join. * HAVING and IS NULL or IS NOT NULL now works. * A group on one column and a sort on a group function (SUM,AVG...) didn't work together. Fixed. * mysqldump: Didn't send password to server. Changes in release 3.19.4 ------------------------- * Fixed horrible locking bug when inserting in one thread and reading on another thread. * Fixed one-off decimal bug. 1.00 was output as 1.0 * Added attribute 'Locked' to process list as info if a query is locked by another query. * Fixed full magic timestamp. Timestamp length may now be 14,12,10,8,6,4 or 2. * sort on some number functions could be sorted wrong on last number. * if(arg,syntax_error,syntax_error) crashed. * added functions ceiling() and round(), exp(), log() and sqrt() * enchanted BETWEEN to handle strings. Changes in release 3.19.3 ------------------------- * Fixed that select with grouping on blob's doesn't return wrong blob info. grouping, sorting and distinct on blobs will not yet work as expected (Probably it will group/sort by the first 7 characters in the blob). Groping on formulas with a fixed string size (use mid on blob) should work. * When doing a full join (no direct keys) on multiple tables with blob fields, the blob was garbage on output. * Fixed distinct with calculated columns. Known errors and design deficiencies in *MySQL* *********************************************** * You can not build in another directory when using mit-pthreads. Since this requires changes to mit-pthreads we are not likely to fix this. * HAVING can only use fields in select expression list. Functions must be aliased. You must use SELECT grp,COUNT(*) as c FROM table GROUP BY grp HAVING c > 1 instead of SELECT grp FROM table GROUP BY grp HAVING count(*) > 1 * Blobs can't 'reliably' be used in `GROUP BY' or `ORDER BY' or `DISTINCT'. Only the first `max_sort_length' (default 1024) are used when comparing blobs in these cases. This can be changed with the `-O max_sort_length' parameter to mysql. A workaround for most cases is to use a substring: `SELECT DISTINCT LEFT(blob,2048) FROM table'. * Calculation is done with `bigint' or `double' (both are normally 64 bit long). It depends on the function which precision one gets. The general rule is that bit functions are done with bigint precision, IF, and ELT() with bigint or double precision and the rest with double precision. One should try to avoid using bigger unsigned long long values than 63 bits (9223372036854775807) for anything else than bit fields! * All field types are fixed point fields. That means one must specify how many decimals a floating point field shall have. All results will be returned with the correct number of decimals. * All string columns, except BLOBS, have automatically all end spaces removed when retrieved. For CHAR types this is ok may be regarded as a feature according to ANSI SQL92. The bug is that VARCHAR columns are treated the same way. And a compare with a string constat should remove spaces too. For example the following query never returns anything if name isn't a BLOB. `SELECT * FROM table WHERE name = 'david '' * One can only have up to 255 enum and set columns in one table. * Updates that updates a key with a where on the same key may fail because the key is used to search records and will be found multiple times: UPDATE SET KEY=KEY+1 WHERE KEY > 100 This will be fixed by not using keys that contains fields that are going to be updated. * safe_mysqld re-directs all messages from mysqld to the mysqld log. One problem with this is that if you do 'mysqladmin refresh' to close and reopen the log stdout and stderr is still redirected to the old log. If you use -log extensively, you should edit safe_mysqld to log to 'hostname'.err instead of 'hostname'.log so you can easily reclaim the space for the old log by deleting the old one and doing a 'refresh'. For platform specific bugs see the sections about compiling and porting. List of things we want to add to *MySQL* in the future. ******************************************************* Everything in this list is in the order it will be done. If you want to affect the priority order, please register a licence or support us and tell us what you want to have done more quickly. *Note Licensing and Support::. Things what has to be done in the real near future. =================================================== * Optimized MIN(key) and MAX(key). Needed for sub select. * Delayed inserts for log tables. * Subqueries. 'select id from t where grp in (select grp from g where u > 100)' * Use of tables from multiple databases in same query with the syntax: table.column@database. * Redesign the connect code to cache IP's for faster name resolving, check the connection in a separate thread and block IP's that doesn't connect properly. * Optimize some queries to only use keys. * FreeBSD and MIT-threads; Do sleeping threads take CPU? * Allow join on key parts (optimizing issue). * Check why 'delete' uses 'record check' * Fix that temporary HEAP tables is automatically converted to NISAM if they get too big. At the moment one gets 'error 135' or 'Table xxx is full' if one does a query which has to use a big temporary table. * Allow one to store MySQL server and client startup options in global and user files. * Add DISTINCT qualifier to COUNT(), SUM()... * Binary portable data tables (a new version of ISAM) * Change conv_blob to handle blob as a text field. * Entry for DECRYPT() and ENCRYPT(); * Functions << and >> (like in C). * Fix libmysql.c to allow two mysql_query() commands in a row without reading results or give a nice error message when one does this. * Remember FOREIGN key definitions in the .frm file. * Optimize BIT type to take 1 bit (now BIT takes 1 char). * Check why MIT-threads ctime() doesn't work on some FreeBSD systems. * Check if locked threads take any cpu. * Add ORDER BY to update. This would be handy with functions like: generate_id(start,step). * Add a IMAGE option to LOAD DATA INFILE to not update timestamps and auto increment fields. * Demo procedure: analyze * HAVING + group functions without alias: select name from company group by name having count(*) > 1 * Automatic output from 'mysql' to netscape. * LOCK DATABASES. (with various options) * NATURAL JOIN * Change sort to alloc memory in 'hunks' to get better memory utilisation. * Add functions BIN(),HEX() and CONV(number,base) * Add ANSI SQL EXTRACT function. * Add functions: MAKE_SET(set_bits,'aaa,bbb,ccc,ddd,eee") -> Returns a set string. MAKE_SET(1 | 8, 'aaa,bbb,ccc,ddd,eee") -> 'aaa,ddd' EXPORT_SET(set_column,'Y','N',[separator],[number_of_set_values]) where separator is ',' as default and number_of_set_values is taken from the set_column (or is 64 if set_column is an expression) EXPORT_SET(9,'Y','N',',',5) -> Y,N,N,Y,N * Add use of 't1 JOIN t2 ON ...' and 't1 JOIN t2 USING ...'. Currently one can only use this syntax with LEFT JOIN. * Add full support for unsigned long long type. * A LOCK DATABASE function (for backup's) * Function CASE * Functions LPAD and RPAD. lpad('hi',4,'??') -> '??hi' rpad('hi',4,'??') -> 'hi??' Things that have to be done sometime. ===================================== * Implement a table optimiser by a analyze procedure call that returns a table like show fields with min and max value and the best *MySQL* type for that expression. * Implement function: get_changed_tables(timeout,table1,table2,...) Implement function: LAST_UPDATED(table_name) * Atomic updates; This includes a language that one can even use for a set of stored procedures. * update items,month set items.price=month.price where items.id=month.id; * Change reading through tables to use memmap when possible. Now only compressed tables use memmap. * Make a SQL standard GRANT command with *MySQL* extensions. * Change CREATE INDEX to use ALTER TABLE or add secondary indexes. * Change DROP INDEX to use ALTER TABLE or use secondary indexes. * Add a new privilege 'Show_priv' for 'SHOW' commands. * Make the automatic timestamp code nicer. Add timestamps to the update log with SET TIMESTAMP=#; * Optimize the autoincrement code. * Use read/write mutex in some places to get more speed. * Full foreign key support. One probably wants to implement a procedural language first. * Simple views (first on one table, later on any expression). * Automatic close some tables if a table, temporary table or temporary files gets error 23 (Not enough open files). * When one finds a field=#, change all occurrence of field to #. Now this is only done for some simple cases. * Change all const expression with calculated expressions if possible. * Optimize key = expression. At the moment only key = field or key = constant are optimised. * Join some of the copy functions for nicer code. * Change sql_yacc.y to an inline parser to get down it's size and get better error messages (5 days) * Change the parser to use only one rule per different number of arguments in function. * Use of full calculation names in the order part. (For ACCESS97) * UNION and FULL OUTER JOIN. (Currently only LEFT OUTER JOIN is supported) * Allow UNIQUE on fields that can be NULL. * SQL_OPTION MAX_SELECT_TIME=#to put a time limit on a query. * Make the update log to a database. * Negative LIMIT to retrieve data from the end. * Alarm round client connect/read/write functions. * Add own hostname-ip memory table for cached reverse name lookup. * Make a mysqld version which isn't multithreaded (2-4 days). * Please note the changes to safe_mysqld: according to FSSTND (which Debian tries to follow) PID files should go into /var/run/.pid and log files into /var/log. It would be nice if you could put the "DATADIR" in the first declaration of "pidfile" and "log", so the placement of these files can be changed with a single statement. * Add '-drop' command to mysqldump to start output with a drop of all tables. * Better dynamic record layout to avoid fragmentation. * UPDATE SET blob=read_blob_from_file('my_gif') where id=1; * Add long query count (configurable time limit) to mysqladmin status. * Allow sorting on RAND(): SELECT email,RAND() AS ran FROM info ORDER BY ran; * Allow a client to request logging. * Allow one to insert, with ALTER TABLE, a new column between old columns. * insert into bar (yobabyyo) values (1),(2),(3); * Add use of zlib() for gziped files to LOAD DATA INFILE. * Fix sorting and grouping of blobs (partly solved now). * Stored procedures. This is currently not regarded to be very important as stored procedures are not very standardized yet. Another problem is that true stored procedures makes it much harder for the optimizer and in many cases the result is slower than before We will on the other hand add a simple atomic) update language that can be used to write loops and such in the MySQL server. Time is given according to amount of work, not real time. TcX's main business is the use of *MySQL* not the development of it. But since TcX is a very flexible company and we have put a lot of resources into the development of *MySQL*. Some things we don't have any plans to do. ========================================== * Transactions with rollback (we mainly do selects, and because we don't do transactions we can be much quicker on everything else). We will support some kind of atomic operations on multiple tables though. Currently atomic operations can be done with `LOCK TABLES'/`UNLOCK TABLES' but we will make this more automatic in the future. Comments on porting to other systems. ************************************* 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 are not good enough) and on Linux we use LinuxThreads by Xavier Leroy . The hard part of porting to a new UNIX variant without good native thread support is probably to port MIT threads. See `mit-pthreads/README' and Programming POSIX Threads (http://www.humanfactor.com/pthreads/). The *MySQL* distribution includes a patched version of Provenzano's Pthreads from MIT (see MIT Pthreads web page (http://www.mit.edu:8001/people/proven/pthreads.html)). This can be used for some operating systems that does not have posix threads. It is also possible to use another user level thread package named FSU Pthreads (see FSU pthread home page (http://www.informatik.hu-berlin.de/~mueller/pthreads.html)). 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 needs a working C++ compiler (we use gcc and have tried SparcWorks). Other compiler that is known to work is the IRIX cc. To compile only the client use `./configure --without-server' There currently no support for only compiling the server. Nor is it likly to be added unless someone has a good reason for it. If you want/need to change any Makefile or the configure script you must get automake and autoconf. We have used autoconf-2.12 and automake-1.2. 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=yes --prefix='your installation directory' # The makefiles generated above needs GNU make (called gmake below) gmake clean all install init-db Debugging *MySQL* ================= If you have some very specific problem, you can always try to debug MySQL. To do this you must configure *MySQL* with the option `--with-debug=yes' Start the mysql server with a trace log in /tmp/mysql.trace. The log file will get very *BIG*. `mysqld --debug' or you can start it with `mysqld --debug=d,info,error,query,general,where:O,/tmp/mysql.trace' which only prints information with the most interesting tags. On most system (except Linux) you can also start mysqld in `gdb' to get more information if mysqld crashes. Comments about RTS threads: =========================== I have tried to use the RTS thread packages with *MySQL* but stumbled on the following problems: They use old version of a lot of 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 already written. Se mysys/my_pthread.c for more info. At least the following should be changed: pthread_get_specific should use on 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 uses 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 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 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 is 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 one the right track. Here follows an successful run on Solaris: Main thread: 1 Tread 0 (5) started Thread: 5 Waiting process_alarm Tread 1 (6) started Thread: 6 Waiting process_alarm process_alarm thread_alarm Thread: 6 Sleeped for 1 (1) sec Thread: 6 Waiting process_alarm process_alarm thread_alarm Thread: 6 Sleeped for 2 (2) sec Thread: 6 Simulation of no alarm needed Thread: 6 Sleeped for 0 (3) sec Thread: 6 Waiting process_alarm process_alarm thread_alarm Thread: 6 Sleeped for 4 (4) sec Thread: 6 Waiting process_alarm thread_alarm Thread: 5 Sleeped for 10 (10) sec Thread: 5 Waiting process_alarm process_alarm thread_alarm Thread: 6 Sleeped for 5 (5) sec Thread: 6 Waiting process_alarm process_alarm ... thread_alarm Thread: 5 Sleeped for 0 (1) sec end What is the difference between different thread packages? ========================================================= *MySQL* is very dependent on the used thread package. 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 not thread- safe functions with locks. Read, write and select 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-threads, FSU-threads and RTS threads). In some environments (for example SCO), all system calls are thread- safe so the mapping can be done very easily (FSU-threads 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-threads and sockets). Thread scheduling isn't always optimal. * User threads in separate processes. Thread switching is done by the kernel and all data is 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 one has to 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 'ps' may on some systems show the different threads. If one thread aborts the whole process aborts. Most system calls are threadsafe and should require very little overhead. Solaris, HP/UX, AIX and OSF1 has 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'. Description of *MySQL* regular expression syntax. ************************************************* Regular expressions are a powerful way of specifying complex searches. *MySQL* uses regular Henry Spencers inplementation of regular expressions. And that is aimed to conform to POSIX 1003.2. *MySQL* uses the extended version. To get more exact information see Henry Spencers regex.7 manual that is included in the source distribution. *Note Credits::. This is a simplistic reference that skips the details. From here on a regualr expressions is called a regexp. A regular expression describes a set of strings. The simplest case is one that has no special characters in it. For example the regexp `hello' matches `hello' and nothing else. Nontrivial regular expressions use certain special constructs so that they can match more than one string. For example, the regexp `hello|word' matches either the string `hello' or the string `word'. And a more comples example regexp `B[an]*s' matches any of the strings `Bananas', `Baaaaas', `Bs' and all other string starting with a `B' and continuing with any number of `a' `n' and ending with a `s'. The following special characters/constructs are known. `^' Start of whole string. mysql> select "fo\nfo" regexp "^fo$"; -> 0 mysql> select "fofo" regexp "^fo"; -> 1 `$' End of whole string. mysql> select "fo\no" regexp "^fo\no$"; -> 1 mysql> select "fo\no" regexp "^fo$"; -> 0 `.' Any character (including newline). mysql> select "fofo" regexp "^f.*"; -> 1 mysql> select "fo\nfo" regexp "^f.*"; -> 1 `a*' Any sequence of zero or more a's. mysql> select "Ban" regexp "^Ba*n"; -> 1 mysql> select "Baaan" regexp "^Ba*n"; -> 1 mysql> select "Bn" regexp "^Ba*n"; -> 1 `a+' Any sequence of one or more a's. mysql> select "Ban" regexp "^Ba+n"; -> 1 mysql> select "Bn" regexp "^Ba+n"; -> 0 `a?' Either zero or one a. mysql> select "Bn" regexp "^Ba?n"; -> 1 mysql> select "Ban" regexp "^Ba?n"; -> 1 mysql> select "Baan" regexp "^Ba?n"; -> 0 `de|abc' Either the sequence `de' or `abc'. mysql> select "pi" regexp "pi|apa"; -> 1 mysql> select "axe" regexp "pi|apa"; -> 0 mysql> select "apa" regexp "pi|apa"; -> 1 mysql> select "apa" regexp "^(pi|apa)$"; -> 1 mysql> select "pi" regexp "^(pi|apa)$"; -> 1 mysql> select "pix" regexp "^(pi|apa)$"; -> 0 `(abc)*' Zero or more times the sequence `abc'. mysql> select "pi" regexp "^(pi)+$"; -> 1 mysql> select "pip" regexp "^(pi)+$"; -> 0 mysql> select "pipi" regexp "^(pi)+$"; -> 1 `{1}' `{2,3}' The is a more general way of writing regexps that match many occurences. `a*' Can be written as `a{0,}'. `+' Can be written as `a{1,}'. `?' Can be written as `a{0,1}'. To be more precice an atom followed by a bound containing one integer `i' and no comma matches a sequence of exactly `i' matches of the atom. An atom followed by a bound containing one integer `i' and a comma matches a sequence of `i' or more matches of the atom. An atom followed by a bound containing two integers `i' and `j' matches a sequence of `i' through `j' (inclusive) matches of the atom. Both arguments must `0 >= value <= RE_DUP_MAX (default 255)', and if there are two of them, the second must be bigger or equal to the first. `[a-dX]' `[^a-dX]' Any character which is (not if ^ is used) either `a', `b', `c', `d' or `X'. To include `]' it has to be written first. To include `-' it has to be written first or last. So `[0-9]' matches any decimal digit. All character that does not have a defined mening inside a `[]' pair has no special meaning and matches only itself. mysql> select "aXbc" regexp "[a-dXYZ]"; -> 1 mysql> select "aXbc" regexp "^[a-dXYZ]$"; -> 0 mysql> select "aXbc" regexp "^[a-dXYZ]+$"; -> 1 mysql> select "aXbc" regexp "^[^a-dXYZ]+$"; -> 0 mysql> select "gheis" regexp "^[^a-dXYZ]+$"; -> 1 mysql> select "gheisa" regexp "^[^a-dXYZ]+$"; -> 0 `[[.characters.]]' The sequence of characters of that collating element. The sequence is a single element of the bracket expression's list. A bracket expression containing a multi-character collating element can thus match more than one character, e.g. if the collating sequence includes a `ch' collating element, then the RE `[[.ch.]]*c' matches the first five characters of `chchcc'. `[=character-class=]' An equivalence class, standing for the sequences of characters of all collating elements equivalent to that one, including itself. For example, if `o' and `(+)' are the members of an equivalence class, then `[[=o=]]', `[[=(+)=]]', and `[o(+)]' are all synonymous. An equivalence class may not be an endpoint of a range. `[:character_class:]' Within a bracket expression, the name of a character class enclosed in `[:' and `:]' stands for the list of all characters belonging to that class. Standard character class names are: alnum digit punct alpha graph space blank lower upper cntrl print xdigit These stand for the character classes defined in ctype(3). A locale may provide others. A character class may not be used as an endpoint of a range. mysql> select "justalnums" regexp "[[:alnum:]]+"; -> 1 mysql> select "!!" regexp "[[:alnum:]]+"; -> 0 `[[:<:]]' `[[:>:]]' These match the null string at the beginning and end of a word respectively. A word is defined as a sequence of word characters which is neither preceded nor followed by word characters. A word character is an alnum character (as defined by ctype(3)) or an underscore. mysql> select "a word a" regexp "[[:<:]]word[[:>:]]"; -> 1 mysql> select "a xword a" regexp "[[:<:]]word[[:>:]]"; -> 0 mysql> select "weeknights" regexp "^(wee|week)(knights|nights)$"; -> 1 What is UNIREG ? **************** Unireg is our tty interface builder, but it uses a low level connection to our NISAM (which is used by *MySQL*) and because of this it is very quick. It has existed since 1979 (on Unix in C since ~1986). Unireg has the following components: * One table viewer with updates/browsing. * Multi table viewer (with one scrolling region). * Table creator. (With lots of column tags you can't create with *MySQL*) This is WYSIWYG (for a tty). You design a screen and Unireg prompts for the column specification. * Report generator. * A lot of utilities (Quick export/import of tables to/from text files, analysis of table contents...). * Powerful multi-table updates (which we use a lot) with a BASIC like language with LOTS of functions. * Dynamic languages (at present in Swedish and Finnish). If somebody wants an English version there are a few files that would have to be translated. * The ability to run updates interactively or in a batch. * Emacs like key definitions with keyboard macros. * All this in a binary of 800k. * The convform utility. Changes .frm and text files between different character sets. * The pack_isam utility. Packs a NISAM table (makes it 50-80% smaller). The table can be read by *MySQL* like an ordinary table. Only one record has to be decompressed / access. Cannot handle BLOB:s or updates (yet). We update most of our production databases with the UNIREG interface and serve web pages through *MySQL* (and in some extreme cases the UNIREG report generator). Unireg takes about 3M of disk space and works on at least the following platforms: SUN OS 4.x, Solaris, Linux, HP/UX, ICL Unix, DNIX, SCO and MSDOS. Unireg is currently only available in Swedish and Finnish. The price tag for UNIREG is 10,000 Swedish kr (about 1500$ US), but this includes support. UNIREG is distributed as a binary. (But all the ISAM sources can be found in *MySQL*). Usually we compile the binary for the customer at their site. All new development is concentrated to *MySQL*. The *MySQL* server license ************************** *MySQL FREE PUBLIC LICENSE* (Version 4, March 5, 1995) Copyright (C) 1995, 1996 TcX AB & Monty Program KB & Detron HB Stockholm SWEDEN, Helsingfors FINLAND and Uppsala SWEDEN All rights reserved. NOTE: This license is not the same as any of the GNU Licenses published by the Free Software Foundation. Its terms are substantially different from those of the GNU Licenses. If you are familiar with the GNU Licenses, please read this license with extra care. This License applies to the computer program known as "MySQL". The "Program", below, refers to such program, and a "work based on the Program" means either the Program or any derivative work of the Program, as defined in the United States Copyright Act of 1976, such as a translation or a modification. The Program is a copyrighted work whose copyright is held by TcX Datakonsult AB and Monty Program KB and Detron HB. This License does not apply when running "MySQL" on any Microsoft operating system. Microsoft operating systems include all versions of Microsoft Windows NT and Microsoft Windows. BY MODIFYING OR DISTRIBUTING THE PROGRAM (OR ANY WORK BASED ON THE PROGRAM), YOU INDICATE YOUR ACCEPTANCE OF THIS LICENSE TO DO SO, AND ALL ITS TERMS AND CONDITIONS FOR COPYING, DISTRIBUTING OR MODIFYING THE PROGRAM OR WORKS BASED ON IT. NOTHING OTHER THAN THIS LICENSE GRANTS YOU PERMISSION TO MODIFY OR DISTRIBUTE THE PROGRAM OR ITS DERIVATIVE WORKS. THESE ACTIONS ARE PROHIBITED BY LAW. IF YOU DO NOT ACCEPT THESE TERMS AND CONDITIONS, DO NOT MODIFY OR DISTRIBUTE THE PROGRAM. 1. Licenses. Licensor hereby grants you the following rights, provided that you comply with all of the restrictions set forth in this License and provided, further, that you distribute an unmodified copy of this License with the Program: a. You may copy and distribute literal (i.e., verbatim) copies of the Program's source code as you receive it throughout the world, in any medium. b. You may modify the Program, create works based on the Program and distribute copies of such throughout the world, in any medium. 2. Restrictions. This license is subject to the following restrictions: a. Distribution of the Program or any work based on the Program by a commercial organization to any third party is prohibited if any payment is made in connection with such distribution, whether directly (as in payment for a copy of the Program) or indirectly (as in payment for some service related to the Program, or payment for some product or service that includes a copy of the Program "without charge"; these are only examples, and not an exhaustive enumeration of prohibited activities). However, the following methods of distribution involving payment shall not in and of themselves be a violation of this restriction: A. Posting the Program on a public access information storage and retrieval service for which a fee is received for retrieving information (such as an on-line service), provided that the fee is not content-dependent (i.e., the fee would be the same for retrieving the same volume of information consisting of random data). B. Distributing the Program on a CD-ROM, provided that the files containing the Program are reproduced entirely and verbatim on such CD-ROM, and provided further that all information on such CD-ROM be redistributable for non-commercial purposes without charge. b. Activities other than copying, distribution and modification of the Program are not subject to this License and they are outside its scope. Functional use (running) of the Program is not restricted, and any output produced through the use of the Program is subject to this license only if its contents constitute a work based on the Program (independent of having been made by running the Program). c. You must meet all of the following conditions with respect to the distribution of any work based on the Program: A. If you have modified the Program, you must cause your work to carry prominent notices stating that you have modified the Program's files and the date of any change; B. You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole and at no charge to all third parties under the terms of this License; C. If the modified program normally reads commands interactively when run, you must cause it, at each time the modified program commences operation, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty). Such notice must also state that users may redistribute the Program only under the conditions of this License and tell the user how to view the copy of this License included with the Program. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.); D. You must accompany any such work based on the Program with the complete corresponding machine-readable source code, delivered on a medium customarily used for software interchange. The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable code. However, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable code; E. If you distribute any written or printed material at all with the Program or any work based on the Program, such material must include either a written copy of this License, or a prominent written indication that the Program or the work based on the Program is covered by this License and written instructions for printing and/or displaying the copy of the License on the distribution medium; F. You may not impose any further restrictions on the recipient's exercise of the rights granted herein. If distribution of executable or object code is made by offering the equivalent ability to copy from a designated place, then offering equivalent ability to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source code along with the object code. 3. Reservation of Rights. No rights are granted to the Program except as expressly set forth herein. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 4. Other Restrictions. If the distribution and/or use of the Program is restricted in certain countries for any reason, Licensor may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 5. Limitations. THE PROGRAM IS PROVIDED TO YOU "AS IS," WITHOUT WARRANTY. THERE IS NO WARRANTY FOR THE PROGRAM, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL LICENSOR, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SQL command, type and function index. ************************************* * Menu: * !: Logical functions. * !=: Comparison functions. * %: Mathematical functions. * &: Bit functions. * &&: Logical functions. * (: Grouping functions. * ): Grouping functions. * *: Arithmetic functions. * +: Arithmetic functions. * - <1>: Arithmetic functions. * -: Mathematical functions. * /: Arithmetic functions. * <: Comparison functions. * <=: Comparison functions. * <>: Comparison functions. * =: Comparison functions. * >: Comparison functions. * >=: Comparison functions. * A BETWEEN B AND C: Comparison functions. * ABS(): Mathematical functions. * ACOS(X): Mathematical functions. * ALTER TABLE: Create table. * AND: Logical functions. * Aritmetic functions: Arithmetic functions. * ASCII(S): String functions. * ASIN(X): Mathematical functions. * ATAN(X): Mathematical functions. * ATAN2(X,Y): Mathematical functions. * AVG(expr): Group by functions. * BIGINT: Column types. * Bit functions: Arithmetic functions. * BIT_AND(expr): Group by functions. * BIT_COUNT(): Bit functions. * BIT_OR(expr): Group by functions. * BLOB: Column types. * BLOB (Generic): Type details. * CEILING(): Mathematical functions. * CHAR: Column types. * CHAR(X,...): String functions. * CHAR_LENGTH(S): String functions. * CHARACTER_LENGTH(S): String functions. * ChopBlanks: Perl DBI Class. * Comment syntax: Drop Index. * Comparison operators: Logical functions. * CONCAT(X,Y...): String functions. * connect: Perl DBI Class. * Control flow functions: String comparison functions. * COS(X): Mathematical functions. * COT(N): Mathematical functions. * COUNT(Expr): Group by functions. * CREATE DATABASE: Group by functions. * CREATE FUNCTION: Comments. * CREATE INDEX: Grant. * CREATE TABLE: Drop database. * CURDATE(): Date and time functions. * CURRENT_DATE(): Date and time functions. * CURRENT_TIME(): Date and time functions. * CURRENT_TIMESTAMP(): Date and time functions. * CURTIME(): Date and time functions. * data_sources: Perl DBI Class. * DATABASE(): Miscellaneous functions. * DATE: Column types. * Date and time functions: String functions. * DATE_FORMAT(Date, Format): Date and time functions. * DATETIME: Column types. * DAYNAME(date expr): Date and time functions. * DAYOFMONTH(date expr): Date and time functions. * DAYOFWEEK(date expr): Date and time functions. * DAYOFYEAR(date expr): Date and time functions. * DECIMAL: Column types. * DEGREES(N): Mathematical functions. * DELETE: Delete table. * DELETE TABLE: Alter table. * DESC: Explain. * DESCRIBE: Explain. * disconnect: Perl DBI Class. * do: Perl DBI Class. * DOUBLE PRECISION: Column types. * DROP DATABASE: Create database. * DROP FUNCTION: Comments. * DROP INDEX: Create Index. * ELT(N, A1, A2, A3...): String functions. * ENCRYPT(String[, Salt]): Miscellaneous functions. * ENUM <1>: Column types. * ENUM: Type details. * execute: Perl DBI Class. * EXP(N): Mathematical functions. * EXPLAIN: Show. * expr IN (value,...): String comparison functions. * expr LIKE expr: String comparison functions. * expr NOT IN (value,...): String comparison functions. * expr NOT LIKE expr: String comparison functions. * expr NOT REGEXP expr: String comparison functions. * expr REGEXP expr: String comparison functions. * fetchall_arrayref: Perl DBI Class. * fetchrow_array: Perl DBI Class. * fetchrow_arrayref: Perl DBI Class. * fetchrow_hashref: Perl DBI Class. * FIELD(S, S1, S2, S3...): String functions. * FIND_IN_SET(string,string of strings): String functions. * finish: Perl DBI Class. * FLOAT: Column types. * FLOAT(4): Column types. * FLOAT(8): Column types. * FLOAT(M,D): Column types. * FLOOR(): Mathematical functions. * FORMAT(Nr, Num): Miscellaneous functions. * FROM_DAYS(): Date and time functions. * FROM_UNIXTIME(Unix_timestamp): Date and time functions. * FROM_UNIXTIME(Unix_timestamp, Format_string): Date and time functions. * GET_LOCK(String,timeout): Miscellaneous functions. * GRANT: Set option. * Group by functions: Miscellaneous functions. * HOUR(time expr): Date and time functions. * IF(A,B,C): Control flow functions. * IFNULL(A,B): Control flow functions. * INSERT: Join. * INSERT(Org, Start, Length, New): String functions. * insertid: Perl DBI Class. * INSTR(A,B): String functions. * INT: Column types. * INTERVAL(N, N1, N2, N3...): String functions. * is_blob: Perl DBI Class. * is_key: Perl DBI Class. * is_not_null: Perl DBI Class. * is_num: Perl DBI Class. * is_pri_key: Perl DBI Class. * ISNULL(A): Comparison functions. * JOIN: Select. * LAST_INSERT_ID(): Miscellaneous functions. * LCASE(A): String functions. * LEFT JOIN: Select. * LEFT(str,length): String functions. * length: Perl DBI Class. * LENGTH(S): String functions. * LIKE: String comparison functions. * LOAD DATA INFILE: Replace. * LOCATE(A,B): String functions. * LOCATE(A,B,C): String functions. * LOCK TABLES: Describe. * LOG(X): Mathematical functions. * LOG10(X): Mathematical functions. * Logical functions: Bit functions. * LONGBLOB: Column types. * LONGTEXT: Column types. * LOWER(A): String functions. * LTRIM(str): String functions. * Mathematical functions: Control flow functions. * MAX(expr): Group by functions. * MAX(X,Y...): Mathematical functions. * max_length: Perl DBI Class. * MEDIUMBLOB: Column types. * MEDIUMINT: Column types. * MEDIUMTEXT: Column types. * MID(A, B, C): String functions. * MIN(expr): Group by functions. * MIN(X,Y...): Mathematical functions. * MINUTE(time expr): Date and time functions. * Miscellaneous functions: Date and time functions. * MOD(): Mathematical functions. * MONTH(date expr): Date and time functions. * MONTHNAME(date expr): Date and time functions. * mysql_affected_rows: C. * mysql_close: C. * mysql_connect: C. * mysql_create_db: C. * mysql_data_seek: C. * mysql_drop_db: C. * mysql_eof: C. * mysql_error: C. * mysql_escape_string: C. * mysql_fetch_field: C. * mysql_fetch_lengths: C. * mysql_fetch_row: C. * mysql_field_seek: C. * mysql_free_result: C. * mysql_get_client_info: C. * mysql_get_host_info: C. * mysql_get_proto_info: C. * mysql_get_server_info: C. * mysql_insert_id: C. * mysql_list_dbs: C. * mysql_list_fields: C. * mysql_list_processes: C. * mysql_list_tables: C. * mysql_num_fields: C. * mysql_num_rows: C. * mysql_query: C. * mysql_real_query: C. * mysql_reload: C. * mysql_select_db: C. * mysql_shutdown: C. * mysql_stat: C. * mysql_store_result: C. * mysql_use_result: C. * NAME: Perl DBI Class. * NOT: Logical functions. * NOW(): Date and time functions. * NULLABLE: Perl DBI Class. * NUM_OF_FIELDS: Perl DBI Class. * NUMERIC: Column types. * OCTET_LENGTH(S): String functions. * OR: Logical functions. * Parenthesis: Grouping functions. * PASSWORD(String): Miscellaneous functions. * PERIOD_ADD(P, N): Date and time functions. * PERIOD_DIFF(A, B): Date and time functions. * PI(): Mathematical functions. * POSITION(B IN A): String functions. * POW(X,Y): Mathematical functions. * POWER(X,Y): Mathematical functions. * prepare: Perl DBI Class. * QUARTER(date expr): Date and time functions. * quote: Perl DBI Class. * RADIANS(N): Mathematical functions. * RAND([X]): Mathematical functions. * REAL: Column types. * RELEASE_LOCK(String): Miscellaneous functions. * REPEAT(String, Count): String functions. * REPLACE: Insert. * REPLACE(A, B, C): String functions. * REVERSE(String): String functions. * RIGHT(A,B): String functions. * ROUND(N): Mathematical functions. * ROUND(Number,Decimals): Mathematical functions. * rows: Perl DBI Class. * RTRIM(str): String functions. * SEC_TO_TIME(Seconds): Date and time functions. * SECOND(time expr): Date and time functions. * SELECT: Delete. * SESSION_USER(): Miscellaneous functions. * SET <1>: Column types. * SET: Type details. * SET OPTION: Lock tables. * SHOW COLUMNS: Update. * SHOW DATABASES: Update. * SHOW FIELDS: Update. * SHOW INDEXE: Update. * SHOW KEYS: Update. * SHOW STATUS: Update. * SHOW TABLES: Update. * SHOW VARIABLES: Update. * SIGN(): Mathematical functions. * SIN(X): Mathematical functions. * SMALLINT: Column types. * SOUNDEX(S): String functions. * SPACE(N): String functions. * sqrt(X): Mathematical functions. * STD(expr): Group by functions. * STDDEV(expr) (Oracle format): Group by functions. * STRCMP(): String comparison functions. * String comparison functions: Comparison functions. * String functions: Mathematical functions. * SUBSTRING(A FROM B FOR C): String functions. * SUBSTRING(A FROM B): String functions. * SUBSTRING(A, B, C): String functions. * SUBSTRING_INDEX(String, Delimiter, Count): String functions. * SUM(expr): Group by functions. * SYSDATE(): Date and time functions. * SYSTEM_USER(): Miscellaneous functions. * table: Perl DBI Class. * TAN(X): Mathematical functions. * TEXT: Column types. * TEXT (Generic): Type details. * TIME: Column types. * TIME_FORMAT(time expr, format): Date and time functions. * TIME_TO_SEC(Time): Date and time functions. * TIMESTAMP <1>: Type details. * TIMESTAMP: Column types. * TINYBLOB: Column types. * TINYINT: Column types. * TINYTEXT: Column types. * TO_DAYS(Date): Date and time functions. * TRIM([[ BOTH | LEADING | TRAILING] [ A ] FROM ] B): String functions. * TRUNCATE(Number, Decimals): Mathematical functions. * Types: Column types. * UCASE(A): String functions. * UDF functions: Comments. * UNIX_TIMESTAMP([date expression]): Date and time functions. * UNLOCK TABLES: Describe. * UPDATE: Load. * UPPER(A): String functions. * USER(): Miscellaneous functions. * VARCHAR: Column types. * VERSION: Miscellaneous functions. * WEEK(date expr): Date and time functions. * WEEKDAY(date expr): Date and time functions. * YEAR(date expr): Date and time functions. * |: Bit functions. * ||: Logical functions. Concept Index ************* * Menu: * *MySQL*: Introduction. * *MySQL* binary: Getting it. * *MySQL* mailing lists: SQL-Words. * *MySQL* mailing lists, un/subscribing to: SQL-Words. * *MySQL* source: Getting it. * *MySQL* version <1>: Installing. * *MySQL* version: Manual-info. * Aritmetic expressions: Arithmetic functions. * Backup: Replication. * Big5 Chinese character encoding: Using DATE. * Bug reports: Asking questions. * Case sensitivity: Using DATE. * Casts: Logical functions. * Checking a table for errors: Releases. * Chinese: Using DATE. * Choosing types: Type details. * Choosing version: Getting it. * Client libraries: Install-binary. * Commands out of sync: Full table. * Copyright: Contacting us. * Cost: Licensing and Support. * Disk full: Commands out of sync. * Downloading: Installing. * Environment variables.: Tools. * Full disk: Commands out of sync. * Functions for select & where: Indexes. * General Information: Top. * Getting *MySQL*: Installing. * Grouping of expressions: Functions. * How to pronounce *MySQL*: What-is. * Index: Memory use. * Indexes: Choosing types. * Keys: Choosing types. * Linking: Install-binary. * Manual information: What-is. * Memory use: Compile and link options. * Net etiquette <1>: Crashing. * Net etiquette: Mailing-list. * ODBC: Adding functions. * optimizations: MySQL indexes. * Overview: Top. * Pack-ISAM: Low-level-table-info. * Paying: Support. * Performance: Table size. * Protocol mismatch: Upgrading-from-3.20. * Quoting of binary data: Base Syntax. * Release numbers: Getting it. * Release policy: Stability. * Replication: Common problems. * Reporting errors: SQL-Words. * Reserved words: UDF functions. * Server functions: Year 2000 compilant. * Size of tables: Update log. * Stability: Stabilty. * Startup parameters: Performance. * Strings, How to escape things: Syntax. * Support: Cost. * Table size: Update log. * The table is full: Packet to large. * TODO: Bugs. * Type conversions: Logical functions. * Type portability: Indexes. * Types, Choosing: Type details. * Update log: Languages. * Version, Choosing: Getting it. * Version, Latest: Installing. * Which languages are supported by *MySQL*?: Server. * Windows: Adding functions. * Year 2000 compilant: Upgrading-from-3.20.