ศุกร์, 18 เม.ย. 2014
 
 

SMSKP-PayPal

Donate using PayPal
Amount:
Note:
Note:

PTT Oil Price

Gold Status

SM SKP ADS-1

สมุยสเก็ตอัพ คอมมิวนิตี้
Newsfeeds
Planet MySQL
Planet MySQL - http://www.planetmysql.org/

  • Biebermarks
    Yet another microbenchmark result. This one is based on behavior that has caused problems in the past for a variety of reasons which lead to a few interesting discoveries. The first was that using a short lock-wait timeout was better than the InnoDB deadlock detection code. The second was that no-stored procedures could overcome network latency.The workload is a large database where all updates are done to a small number of rows. I think it is important to use a large database to include the overhead from searching multiple levels of a b-tree. The inspiration for this is maintaining counts for popular entities like Justin Bieber and One Direction. This comes from serving the social graph. For more on that read about TAO and LinkBench.The most popular benchmark for MySQL is sysbench and it is usually run with a uniform distribution so that all rows are equally likely to be queried or modified. But real workloads have skew which can cause stress in unexpected places and I describe one such place within InnoDB from this microbenchmark. YCSB and LinkBench are benchmarks that have skew and can be run for MySQL. I hope that more of the MySQL benchmark results in the future include skew.ConfigurationSee a previous post for more details. Eight collections/tables with 400M documents/rows per collection/table were created. All collections/tables are in one database so MongoDB suffers from the per-database RW-lock. But MySQL and TokuMX also suffer from a similar issue when all clients are trying to update the same row. Tests were run for 1, 2, 4 and 8 tables where one row per table was updated. So when the test used 4 tables there were 4 rows getting updates. For each number of tables tests were run for up to 64 concurrent clients/threads. The result tables listed in the next section should make that clear.The workload is updating the non-indexed column of one document/row by PK per transaction. There are no secondary indexes on the table. In this case the document/row with ID=1 is chosen for every update. For MySQL and TokuMX an auto-commit transaction is used. The journal (redo log) is used but the update does not wait for the journal/log to be forced to disk. The updates should not require disk reads as all relevant index and data blocks remain in cache. TokuMX might do reads in the background to maintain fractal trees but I don't understand their algorithm to be certain.The database was loaded in PK order and about 8 hours of concurrent & random updates were done to warmup the database prior to this test. The warmup was the same workload as described in a previous post.The MySQL test client limits clients to one table. So when there are 64 clients and 8 tables then there are 8 clients updating the 1 row per table. The MongoDB/TokuMX client does not do that. It lets all clients update all tables so in this case there are at most 64 clients updating the row per table and on average there would be 8.The test server has 40 CPU cores with HT enabled, fast flash storage and 144G of RAM. The benchmark client and database servers shared the host. Tests were run for several configurations:mongo26 - MongoDB 2.6.0rc2, powerOf2Sizes=1, journalCommitInterval=300, w:1,j:0mongo24 - MongoDB 2.6.0rc2, powerOf2Sizes=0, journalCommitInterval=300, w:1,j:0mysql - MySQL 5.6.12, InnoDB, no compression, flush_log_at_trx_commit=2, buffer_pool_size=120G, flush_method=O_DIRECT, page_size=8k, doublewrite=0, io_capacity=16000, lru_scan_depth=2000, buffer_pool_instances=8, write_io_threads=32, flush_neighbors=0toku-32 - TokuMX 1.4.1, readPageSize=32k, quicklz compression, logFlushPeriod=300, w:1,j:0. I don't have results for toku-32 yet.toku-64 - TokuMX 1.4.1, readPageSize=64k, quicklz compression, logFlushPeriod=300, w:1,j:0Results per DBMSI first list the results by DBMS to show the impact from spreading the workload over more rows/tables. The numbers below are the updates per second rate. I use "DOP=X" to indicate the number of concurrent clients and "DOP" stands for Degree Of Parallelism (it is an Oracle thing). A few conclusions from the results below:MySQL/InnoDB does much better with more tables for two reasons. The first is that it allows for more concurrency. The second is that it avoids some of the overhead in the code that maintains row locks and threads waiting for row locks. I describe that in more detail at the end of this post.MongoDB 2.4.9 is slightly faster than 2.6.0rc2. I think the problem is that mongod requires more CPU per update in 2.6 versus 2.4 and this looks like a performance regression in 2.6 (at least in 2.6.0rc2). I am still profiling to figure out where. More details on this are at the end of the post.MongoDB doesn't benefit from spreading the load over more collections when all collections are in the same database. This is expected given the per-database RW-lock.Updates per secondconfig  #tables  DOP=1  DOP=2  DOP=4  DOP=8  DOP=16  DOP=32  DOP=64mysql         1   8360  15992  30182  24932   23924   23191   21048mysql         2      X  16527  30824  49999   41045   40506   38357mysql         4      X      X  32351  51791   67423   62116   59137mysql         8      X      X      X  54826   80409   73782   68128config  #tables  DOP=1  DOP=2  DOP=4  DOP=8  DOP=16  DOP=32  DOP=64mongo24       1  10212  17844  30204  34003   33895   33564   33451mongo24       2      X  10256  17698  30547   34125   33717   33573mongo24       4      X      X  10670  17690   30903   34027   33586mongo24       8      X      X      X  10379   17702   30920   33758config  #tables  DOP=1  DOP=2  DOP=4  DOP=8  DOP=16  DOP=32  DOP=64mongo26       1   9187  16131  27648  28506   27784   27437   27021mongo26       2      X   9367  16035  27490   28326   27746   27354mongo26       4      X      X   9179  16028   27666   28330   27647mongo26       8      X      X      X   9125   16038   27275   27858config  #tables  DOP=1  DOP=2  DOP=4  DOP=8  DOP=16  DOP=32  DOP=64toku-64       1   7327  12804  16179  12154   11021    9990    8344toku-64       2      X   7173  12690  20483   23064   22354   20349toku-64       4      X      X   7191  12943   21399   33485   40124toku-64       8      X      X      X   7121   12727   22096   38207Results per number of tablesThis reorders the results from above to show them for all configurations at the same number of tables. You are welcome to draw conclusions about which is faster.Updates per secondconfig  #tables  DOP=1  DOP=2  DOP=4  DOP=8  DOP=16  DOP=32  DOP=64mysql         1   8360  15992  30182  24932   23924   23191   21048mongo24       1  10212  17844  30204  34003   33895   33564   33451mongo26       1   9187  16131  27648  28506   27784   27437   27021toku-64       1   7327  12804  16179  12154   11021    9990    8344config  #tables  DOP=1  DOP=2  DOP=4  DOP=8  DOP=16  DOP=32  DOP=64mysql         2      X  16527  30824  49999   41045   40506   38357mongo24       2      X  10256  17698  30547   34125   33717   33573mongo26       2      X   9367  16035  27490   28326   27746   27354toku-64       2      X   7173  12690  20483   23064   22354   20349config  #tables  DOP=1  DOP=2  DOP=4  DOP=8  DOP=16  DOP=32  DOP=64mysql         4      X      X  32351  51791   67423   62116   59137mongo24       4      X      X  10670  17690   30903   34027   33586mongo26       4      X      X   9179  16028   27666   28330   27647toku-64       4      X      X   7191  12943   21399   33485   40124config  #tables  DOP=1  DOP=2  DOP=4  DOP=8  DOP=16  DOP=32  DOP=64mysql         8      X      X      X  54826   80409   73782   68128mongo24       8      X      X      X  10379   17702   30920   33758mongo26       8      X      X      X   9125   16038   27275   27858toku-64       8      X      X      X   7121   12727   22096   38207Row locks for InnoDBI used PMP to understand MySQL/InnoDB on this workload. I frequently saw all user threads blocked on a condition variable with this stack trace. It seems odd that all threads are sleeping. I think the problem is that one thread can run but has yet to be scheduled by Linux. My memory of the row lock code is that it wakes threads in FIFO order and when N threads wait for a lock on the same row then each thread waits on a separate condition variable. I am not sure if this code has been improved in MySQL 5.7. A quick reading of some of the 5.6.12 row lock code showed many mutex operations. Problems in this code have escaped scrutiny in the past because much of our public benchmark activity has used workloads with uniform distributions.pthread_cond_wait@@GLIBC_2.3.2,os_cond_wait,os_event_wait_low2,lock_wait_suspend_thread,row_mysql_handle_errors,row_search_for_mysql,ha_innobase::index_read,handler::read_range_first,handler::multi_range_read_next,QUICK_RANGE_SELECT::get_next,rr_quick,mysql_update,mysql_execute_command,mysql_parse,dispatch_command,do_command,do_handle_one_connection,handle_one_connectionThis was a less frequent stack trace from the test ...lock_get_mode,lock_table_other_has_incompatible,lock_table,row_search_for_mysql,ha_innobase::index_read,handler::read_range_first,handler::multi_range_read_next,QUICK_RANGE_SELECT::get_next,rr_quick,mysql_update,mysql_execute_command,mysql_parse,dispatch_command,do_command,do_handle_one_connection,handle_one_connectionRow locks for TokuMXTokuMX has a similar point at which all threads wait. It isn't a big surprise given that both provide fine-grained concurrency control but there is no granularity finer than a row lock.pthread_cond_timedwait@@GLIBC_2.3.2,toku_cond_timedwait,toku::lock_request::wait,toku_db_wait_range_lock,toku_c_getf_set(__toku_dbc*,,db_getf_set,autotxn_db_getf_set(__toku_db*,,mongo::CollectionBase::findByPK(mongo::BSONObj,mongo::queryByPKHack(mongo::Collection*,,mongo::updateObjects(char,mongo::lockedReceivedUpdate(char,mongo::receivedUpdate(mongo::Message&,,mongo::assembleResponse(mongo::Message&,,mongo::MyMessageHandler::process(mongo::Message&,,mongo::PortMessageServer::handleIncomingMsg(void*)MongoDB 2.4 versus 2.6I get about 1.2X more updates/second with MongoDB 2.4.9 compared to 2.6.0rc2. I think the problem is that 2.6 uses more CPU per update. I will file a bug when I figure out what code is the problem. So far I know the following all of which indicates that the 2.4.9 test is running 1.2X faster than 2.6.0rc2 with 32 client threads and 1 table:I get ~1.2X more updates/second with 2.4.9the Java sysbench client uses ~1.2X more CPU per "top" with 2.4.9the context switch rate is ~1.2X higher with 2.4.9The interesting point is that mongod for 2.4.9 only uses ~1.03X more CPU than 2.6.0rc2 per "top" during this test even though it is doing 1.2X more updates/second. So 2.6.0rc2 uses more CPU per update. I will look at "perf" output and try the GA version of 2.6 to see if this repeats there.

  • MySQL Partitioning – A Quick Look at Partitioning – Separate Your Data for Faster Searches
    In MySQL, partitioning is a way to separate the data in one table into smaller “sub-tables” for better query performance and data management. For example, let’s say that you have a database containing numerous accounting transactions. You could just store all of these transactions in one table, but you only need to keep seven year’s worth of data for tax purposes. Instead of placing all of the data in one table, and then deleting the old data from that table, you could split the table into partitions with each partition representing one year’s worth of data. Then, after seven years, you could delete/drop the old partition. Partitions are flexible, as you can add, drop, redefine, merge, or split existing partitions (there are other options on what you could do with this data as well). Also, if you have a table that is going to contain a lot of rows, partitioning your data would allow your searches to be much faster, as the search can then be limited to a single partition. As of MySQL 5.6, you can split a table into as many as 8192 partitions. Here is the MySQL website’s explanation about partitions: The SQL standard does not provide much in the way of guidance regarding the physical aspects of data storage. The SQL language itself is intended to work independently of any data structures or media underlying the schemas, tables, rows, or columns with which it works. Nonetheless, most advanced database management systems have evolved some means of determining the physical location to be used for storing specific pieces of data in terms of the file system, hardware or even both. In MySQL, the InnoDB storage engine has long supported the notion of a tablespace, and the MySQL Server, even prior to the introduction of partitioning, could be configured to employ different physical directories for storing different databases (see Section 8.11.3.1, “Using Symbolic Links“, for an explanation of how this is done). Partitioning takes this notion a step further, by enabling you to distribute portions of individual tables across a file system according to rules which you can set largely as needed. In effect, different portions of a table are stored as separate tables in different locations. The user-selected rule by which the division of data is accomplished is known as a partitioning function, which in MySQL can be the modulus, simple matching against a set of ranges or value lists, an internal hashing function, or a linear hashing function. The function is selected according to the partitioning type specified by the user, and takes as its parameter the value of a user-supplied expression. This expression can be a column value, a function acting on one or more column values, or a set of one or more column values, depending on the type of partitioning that is used. (From: https://dev.mysql.com/doc/refman/5.6/en/partitioning-overview.html) There are four types of partition options for your data: RANGE – This type of partitioning assigns rows to partitions based on column values falling within a given range. LIST – Similar to partitioning by RANGE, except that the partition is selected based on columns matching one of a set of discrete values. HASH – With this type of partitioning, a partition is selected based on the value returned by a user-defined expression that operates on column values in rows to be inserted into the table. The function may consist of any expression valid in MySQL that yields a nonnegative integer value. An extension to this type, LINEAR HASH, is also available. KEY – This type of partitioning is similar to partitioning by HASH, except that only one or more columns to be evaluated are supplied, and the MySQL server provides its own hashing function. These columns can contain other than integer values, since the hashing function supplied by MySQL guarantees an integer result regardless of the column data type. An extension to this type, LINEAR KEY, is also available. (From: https://dev.mysql.com/doc/refman/5.6/en/partitioning-types.html) This post will just give you one example of how to partition your data, and then how to verify that your query is searching only the correct partition. It doesn’t do you any good if you partition your data but then write queries that perform a table scan to get your results. In this example, I am going to be separating the table data by the year. We are going to create a simple membership table, and partition by RANGE. We will separate the partition by the year that the person joined and we will add one member to each year. Our members table will be very simple, with an ID, the date the person joined, and their first and last name. We will create the partition by using just the YEAR that they joined, while we keep the full date they joined in the joined column. We are also assigning the columns id and joined to be primary keys. Here is the CREATE TABLE statement: CREATE TABLE `members` ( `id` int(5) NOT NULL AUTO_INCREMENT, `joined` date NOT NULL, `lastname` varchar(25) NOT NULL, `firstname` varchar(25) NOT NULL, PRIMARY KEY (`id`,`joined`) ) ENGINE=InnoDB AUTO_INCREMENT=10000 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE ( YEAR(joined)) (PARTITION p0 VALUES LESS THAN (2011) ENGINE = InnoDB, PARTITION p1 VALUES LESS THAN (2012) ENGINE = InnoDB, PARTITION p2 VALUES LESS THAN (2013) ENGINE = InnoDB, PARTITION p3 VALUES LESS THAN (2014) ENGINE = InnoDB, PARTITION p4 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */; Our partitions will contain rows that have joined dates earlier than the dates shown in the PARTITION BY statement. In other words, partition p0 will contain dates earlier than 01/01/2011 (i.e. dates in 2010 or earlier). Partition p2 will contain dates earlier than 01/01/2012 but greater than 12/31/2010 (i.e. dates in 2011). Partition p3 will contains dates for 2013, and p4 will contain dates for 2014 and greater. Before the year 2015 arrives, you will need to add an additional partition for 2015. Of course, you could go ahead and add partitions for the next several years. If you want partition p0 to contain all dates in 2011 (instead of those dates LESS THAN 2011), you can change the VALUES LESS THAN (2011) statement to VALUES IN (2010). But then any values less than 2011 would not be inserted into the database. Now, let’s insert some data. We will insert one row into each partition, and then do a: select id, joined, lastname, firstname from members; to see what our data looks like: mysql> insert into members (firstname, lastname, joined) values ("Mary", "Davis", "2010-01-14"); Query OK, 1 row affected (0.64 sec) mysql> insert into members (firstname, lastname, joined) values ("John", "Hill", "2011-02-12"); Query OK, 1 row affected (0.01 sec) mysql> insert into members (firstname, lastname, joined) values ("Steve", "Johnson", "2012-03-18"); Query OK, 1 row affected (0.01 sec) mysql> insert into members (firstname, lastname, joined) values ("Beth", "Daniels", "2013-04-22"); Query OK, 1 row affected (0.03 sec) mysql> insert into members (firstname, lastname, joined) values ("Bob", "Smith", "2014-05-29"); Query OK, 1 row affected (0.01 sec) mysql> select id, joined, lastname, firstname from members; +-------+------------+----------+-----------+ | id | joined | lastname | firstname | +-------+------------+----------+-----------+ | 10000 | 2010-01-14 | Davis | Mary | | 10001 | 2011-02-12 | Hill | John | | 10002 | 2012-03-18 | Johnson | Steve | | 10003 | 2013-04-22 | Daniels | Beth | | 10004 | 2014-05-29 | Smith | Bob | +-------+------------+----------+-----------+ 5 rows in set (0.00 sec) When you start building your queries, you want to make sure that the query is using the partitions. You can do this by including the EXPLAIN PARTITIONS statement before your select statement. Visit this link you want to learn more about Obtaining Information About Partitions. Since we made the id column a primary key, let’s look at what happens when we do a search by primary key. We will use the EXPLAIN PARTITIONS statement to see what partitions are being used in the search. Let’s look for Mary’s information. She has the ID of 10000. mysql> EXPLAIN PARTITIONS select id, firstname, lastname, joined from members where id = '10000'; +----+-------------+---------+----------------+------+---------------+---------+---------+-------+------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+----------------+------+---------------+---------+---------+-------+------+-------+ | 1 | SIMPLE | members | p0,p1,p2,p3,p4 | ref | PRIMARY | PRIMARY | 4 | const | 5 | NULL | +----+-------------+---------+----------------+------+---------------+---------+---------+-------+------+-------+ 1 row in set (0.05 sec) As you can see under the partitions column, all five partitions (p0,p1,p2,p3,p4) were searched for this information because the partitions were separated by the year, and not the id. So this query would not take advantage of our partitions. Look at what happens when we also include Mary’s joined date along with the id column: mysql> EXPLAIN PARTITIONS select id, firstname, lastname, joined from members where id = '10000' and joined = '2010-01-14'; +----+-------------+---------+------------+-------+---------------+---------+---------+-------------+------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+------------+-------+---------------+---------+---------+-------------+------+-------+ | 1 | SIMPLE | members | p0 | const | PRIMARY | PRIMARY | 7 | const,const | 1 | NULL | +----+-------------+---------+------------+-------+---------------+---------+---------+-------------+------+-------+ 1 row in set (0.00 sec) As you can see, MySQL only had to search in partition p0. Since the joined column was included in the query, MySQL can go to that partition and use the PRIMARY key of id and quickly find the record it needs. Let’s see what we would need to do if you wanted to find all of the members who joined in the year 2010 (like Mary). You would think that you could just use the YEAR function on the joined column. But, you can’t use a function to convert the joined date to a year, as MySQL will need to convert all of the values in the joined columns first, and then it won’t be able to use the partition: mysql> EXPLAIN PARTITIONS select id, firstname, lastname, joined from members where YEAR(joined) = '2010'; +----+-------------+---------+----------------+------+---------------+------+---------+------+------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+----------------+------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | members | p0,p1,p2,p3,p4 | ALL | NULL | NULL | NULL | NULL | 5 | Using where | +----+-------------+---------+----------------+------+---------------+------+---------+------+------+-------------+ 1 row in set (0.03 sec) In this case, you are still having to go through all partitions because of the YEAR function. It would be better to use a range in the WHERE clause to find the members from 2010: mysql> EXPLAIN PARTITIONS select id, firstname, lastname, joined from members where joined '2009-12-31'; +----+-------------+---------+------------+------+---------------+------+---------+------+------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+------------+------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | members | p0 | ALL | NULL | NULL | NULL | NULL | 2 | Using where | +----+-------------+---------+------------+------+---------------+------+---------+------+------+-------------+ 1 row in set (0.00 sec) But what happens when you need to change the partitioned value of the joined date? What if Mary’s date was incorrect, and she really joined in 2011? What happens to the data? When you change the value of the partitioned column, MySQL will move that data to the appropriate partition. Let’s look at Mary’s information again, and also look at the EXPLAIN PARTITIONS statement for the same query. mysql> select id, firstname, lastname, joined from members where id = '10000' and joined = '2010-01-14'; +-------+-----------+----------+------------+ | id | firstname | lastname | joined | +-------+-----------+----------+------------+ | 10000 | Mary | Davis | 2010-01-14 | +-------+-----------+----------+------------+ 1 row in set (0.00 sec) mysql> EXPLAIN PARTITIONS select id, firstname, lastname, joined from members where id = '10000' and joined = '2010-01-14'; +----+-------------+---------+------------+-------+---------------+---------+---------+-------------+------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+------------+-------+---------------+---------+---------+-------------+------+-------+ | 1 | SIMPLE | members | p0 | const | PRIMARY | PRIMARY | 7 | const,const | 1 | NULL | +----+-------------+---------+------------+-------+---------------+---------+---------+-------------+------+-------+ 1 row in set (0.00 sec) We can see that Mary’s data is in partition p0. Now let’s change Mary’s joined date from 2010-01-14 to 2011-05-30, and then run both of the above statements again (but in the query we need to change Mary’s joined date to reflect the new date): mysql> update members set joined = '2011-05-30' where id = '10000'; Query OK, 1 row affected (0.06 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select id, firstname, lastname, joined from members where id = '10000' and joined = '2011-05-30'; +-------+-----------+----------+------------+ | id | firstname | lastname | joined | +-------+-----------+----------+------------+ | 10000 | Mary | Davis | 2011-05-30 | +-------+-----------+----------+------------+ 1 row in set (0.00 sec) mysql> EXPLAIN PARTITIONS select id, firstname, lastname, joined from members where id = '10000' and joined = '2011-05-30'; +----+-------------+---------+------------+-------+---------------+---------+---------+-------------+------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------+------------+-------+---------------+---------+---------+-------------+------+-------+ | 1 | SIMPLE | members | p1 | const | PRIMARY | PRIMARY | 7 | const,const | 1 | NULL | +----+-------------+---------+------------+-------+---------------+---------+---------+-------------+------+-------+ 1 row in set (0.00 sec) We can now see that Mary’s data is now in partition p1. Partitioning data can really add performance to your queries, but only if you know how to write the proper queries to take advantage of the partitioning. Using the EXPLAIN PARTITIONS statement can really help you figure out if your queries are properly working. You can also store separate partitions on separate storage devices (by using innodb_file_per_table), and in MySQL 5.7.4 (or greater), you can even move partitioned tables to another server.   Tony Darnell is a Principal Sales Consultant for MySQL, a division of Oracle, Inc. MySQL is the world’s most popular open-source database program. Tony may be reached at info [at] ScriptingMySQL.com and on LinkedIn.

  • Congratulations Ubuntu, for the wide choice!
    Inspired by Yngve Svendsen’s post, I too think it makes absolute sense to congratulate Ubuntu on the 14.04 LTS release (some server notes - MySQL has a section dedicated to it). Ubuntu users have a lot of server choice today (that’s from all major MySQL ecosystem vendors): MySQL 5.5.35 ships in main. It is the default MySQL. Oracle has committed to providing updates to 5.5 throughout the LTS release cycle of Ubuntu (which is longer than the planned EOL for 5.5). This is why the grant of a Micro Release Exception (MRE). MySQL 5.6.16 ships in universe.  MariaDB 5.5.36 ships in universe. Percona XtraDB Cluster 5.5.34 ships in universe.  Ubuntu’s pitch is being the cloud platform of choice, with OpenStack support. This explains why Percona XtraDB Cluster (the only shipping Galera Cluster variant — no upstream Codership release, and no MariaDB Galera Cluster) is critical infrastructure as its used widely in OpenStack deployments. 451Research estimates that the OpenStack distributions market is worth $82 million in 2014 and $119 million in 2015. Press release had a choice quote from Percona CEO, Peter Zaitsev: “We are very pleased that Percona XtraDB Cluster is included in Ubuntu 14.04 LTS. Many organisations that use MySQL need high availability solutions to ensure that their applications meet the expectations of their users. Percona XtraDB Cluster is an easy to use, open source solution for MySQL clustering which addresses these high availability needs. We continue to see growth in Ubuntu usage by our customers and our open source software users so we are confident that the inclusion of Percona XtraDB Cluster in Ubuntu 14.04 will help spread the adoption of cost-effective, high availability MySQL.” Peter Zaitsev, Co-Founder and CEO at Percona   Related posts: Ubuntu 10.04 LTS released, MariaDB 5.1.44/5.2-BETA VM’s available OpenSUSE users have a choice of database now! Communications, Ubuntu 6.06 LTS & MySQL downloads

  • Percona Software in Ubuntu 14.04 LTS (Trusty Tahr) release
    I’d like to congratulate Canonical with the new Ubuntu 14.04 LTS (Trusty Tahr) Release, it really looks like a great release, and I say it having my own agenda It looks even more great because it comes with a full line of Percona Software. If you install Ubuntu 14.04 and run aptitude search you will find:Percona ToolkitPercona XtraBackupPercona XtraDB ClusterPercona Server (as part of Percona XtraDB Cluster installation)Percona Toolkit and Percona XtraBackup are up to the latest versions, but Percona Server and Percona XtraDB Cluster comes with 5.5 versions, and it is in line with default MySQL version, which again is 5.5.I expect this release will make it much easier for users to get familiar with our software, so you can go and try this today!The post Percona Software in Ubuntu 14.04 LTS (Trusty Tahr) release appeared first on MySQL Performance Blog.

  • Thoughts on Small Datum – Part 1
    A little background… When I ventured into sales and marketing (I’m an engineer by education) I learned I would often have to interpret and simply summarize the business value that is sometimes hidden in benchmarks. Simply put, the people who approve the purchase of products like TokuDB® and TokuMX™ appreciate the executive summary. Therefore, I plan to publish a multipart series here on TokuView where I will share my simple summaries and thoughts on business value for the benchmarks Mark Callaghan (@markcallaghan), a former Google and now Facebook database guru, is publishing on his blog, Small Datum. I’m going to start with his first benchmark post and work my way forward to the newest. And unless I get feedback which suggests this isn’t useful, I will add new posts here as Mark adds new benchmarks there. In the interest of full disclosure, Mark is the brother of Tokutek VP of engineering, Tim Callaghan. Unfortunately for Tokutek, I know this means some of you may discount what he has to say. I hope you will look past the happy coincidence long enough to evaluate his methodology and findings. If you do I am confident you’ll find his work unbiased and informative. The meat & potatoes… With that introduction out of the way, here is how this marketer simply summarizes Mark’s first Small Datum benchmark post. It was published in February of this year and it’s titled Write Amplification: Write-optimized versus Update-in-place. To understand the business value associated with this benchmark you first have to know a little about Write Amplification (WA): WA is an unfortunate characteristic of database applications that utilize SSD media to improve performance.  It can be measured and expressed as the actual number of bytes written in order to create a single byte of stored data.  There’s a good article on the subject over at Wikipedia. Notably, WA degrades performance thereby reducing the gains that come from using SSD. Moreover, because SSD failure is tied to the total number of bytes written over time, WA also reduces the life expectancy of your SSD media. Why should you care about this?  Well, performance problems usually exhibit themselves in the form of dissatisfied users. If your Big Data application is customer-facing that could mean a revenue hit or other undesirable business impacts. Reduced SSD life expectancy obviously leads to increased costs. In his work, Mark uses Facebook’s LinkBench to compare the WA characteristics of MySQL with the InnoDB versus TokuDB storage engines. He uses a number of tuning techniques to minimize WA in InnoDB and compares that to untuned TokuDB which was purpose-built to, among other things, minimize WA by replacing 40-year-old B-Tree Indexes with Tokutek Fractal Tree Indexes. Bottom line: Mark’s WA benchmarks clearly show the WA profile (expressed as total gigabytes written) of TokuDB applications are roughly 1/2 (or better than) that of write-optimized InnoDB applications. This suggests TokuDB applications will perform better while extending the life of your SSD hardware.  To wit, the expected business benefits will include better application performance and user satisfaction plus reduced hardware costs. You can try it for yourself in your own environment by downloading the free community versions of TokuDB (or TokuMX) here and running your own benchmarks using Mark’s methodology as your guide. If you do, I’d love to hear from you. As always, your thoughts and comments are welcome. In Thoughts on Small Datum – Part II: This marketer’s simple summary of Mark’s insertion benchmarks comparing MySQL with InnoDB versus TokuDB and stock MongoDB versus TokuMX (our high-performance distribution of MongoDB).  If you want to get a head start, check out his post Insert Benchmark for InnoDB, MongoDB and TokuMX and Flash Storage.