 |
 |
 |
 |
#210321 - 04/26/01 01:50 PM
Performance
|
Journeyman
Registered: 05/11/99
Posts: 109
Loc: Poland
|
Well, recently I've been dealing with mysql and w3t performance issues a lot.<br />I've got w3t perl installation on a linux box with apache and mysql.<br />The forum has about 250 000 posts and about 4000 users.<br />Until last weekend it run on 2 servers:<br />-httpd-modperl on pentium II 333 (160MB RAM, scsi disk) - load about 0.5 to 1<br />-mysql on dual PIII 850 (256MB RAM, scsi disk) - load about 1 to 3<br /><br />On monday I moved http and mysql to single server with one pentium III 1GHz, 256MB RAM and ide disk (ATA66, 7200rpm).<br />I've also upgraded 5.3perl to 5.4b1.<br /><br />On old servers forum run quite well, could be better, but it was acceptable.<br />On the new server it runs pretty fast...except for the day hours where there are 50-100 concurrent users.<br />Load is going to 20-50 (!), there is a lot of mysql and httpd processes and the forum hangs.<br /><br />The problem is that lots of sql queries are locked.<br />As you know standard mysql table type (myisam) does table locking, which means that when you do an update rest of queries have to wait for update to complete (they are locked because of lock on table).<br />With small tables it isn't a problem, because updates, selects are fast then.<br />The problem starts showing with large tables when queries are longer.<br />From mysql manual:<br />"Table locking is, however, not very good under the following senario: <br /><br />A client issues a SELECT that takes a long time to run. <br />Another client then issues an UPDATE on a used table. This client will wait until the SELECT is finished. <br />Another client issues another SELECT statement on the same table. As UPDATE has higher priority than SELECT, this SELECT will wait for the UPDATE to finish. It will also wait for the first SELECT to finish! "<br /><br />This is common scenario in w3t.<br />Some clients issues selects from w3t_Posts to read/find posts (or ie. count unread posts in all boards), while some other just read some post and are updating read counter for this post, which is in the same table as post.<br /><br />"Some possible solutions to this problem are: <br /><br />1)Try to get the SELECT statements to run faster. You may have to create some summary tables to do this. <br /><br />2)Start mysqld with --low-priority-updates. This will give all statements that update (modify) a table lower priority than a SELECT statement. In this case the last SELECT statement in the previous scenario would execute before the INSERT statement. <br />3)You can give a specific INSERT, UPDATE, or DELETE statement lower priority with the LOW_PRIORITY attribute. <br />4)Start mysqld with a low value for max_write_lock_count to give READ locks after a certain number of WRITE locks. <br />5)You can specify that all updates from a specific thread should be done with low priority by using the SQL command: SET SQL_LOW_PRIORITY_UPDATES=1. See section 7.33 SET Syntax. <br />6) You can specify that a specific SELECT is very important with the HIGH_PRIORITY attribute. See section 7.19 SELECT Syntax. "<br /><br />I've tried --low-priority-updates. Doesn't help. updates of b_counter are locked instead of select and situations looks the same.<br />I've tried max_write_lock_count=1. Better, but also doesn't solve the problem.<br />I've changed updates of b_counter in showthreaded.pl and showflat.pl to have low priority - updates locks again.<br /><br />I wonder what could be done to make w3t more scalable.<br />Split boards to separate tables to make queries faster?<br />Good old times :-) But searching in all forums would be harder.<br /><br />I've noticed that mainly problem is with lots of councurrent 'select count (*) from w3t_Posts' and 'update w3t_posts set b_counter=b_counter+1 where B_main=x'<br />Every hit on a post issues update on b_counter in w3t_posts, which isn't good (even though b_main is a key)<br />I wonder if b_counter could be moved to a new table (along with b_number and b_main) and if it helps.<br /><br />Again from mysql docs:<br />"Concurrent users is not a problem if one doesn't mix updates and selects that needs to examine many rows in the same table."<br /><br />"If you get speed problems with the table locks in MySQL, you may be able to solve these to convert some of your tables to BDB tables. "<br /><br />Well, I've tried BDB. <br />First - it was unstable, mysql (3.23.37max) crashed often.<br />Second - select count(*) is SLOW with berkeley db, becaue it doesn't maintain a count of the number of rows in the table (typical count was about 4 minutes, while it was <1 sec with myisam)<br />Third - w3t_posts grow from 170MB to 400MB with bdb<br /><br />I've also tried to use new innodb tables, but I didn't manage to convert w3t_posts - alter table w3t_posts type=innodb says 'row too big - can't allocate memory' <br /><br />so, do I need to change to postgresql to have row level locking or something could be done with w3t database design or maybe there is some option in mysql which could help<br />I could also buy another pentium 1G, but for how long it helps<br />Deleting old messages is not an option rather.<br /><br />Greetings, Piotr
_________________________
Greetings, Piotr
|
|
Top
|
|
|
|
 |
 |
 |
 |
 |
 |
 |
 |
#210326 - 04/27/01 02:36 PM
Re: Performance
[Re: Sally]
|
Journeyman
Registered: 05/11/99
Posts: 109
Loc: Poland
|
> Is your current version of mysql locking tables by default? <br /><br />mysql uses table locking - it isn't an option, that's the way mysql works when you write to table (see chapters 13.2.8-9 and I.4)<br />locking doesn't appear with selects and sometimes with inserts (new mysql versions use versioning to do concurrent inserts)<br /><br />> Normally, you don't have to lock tables, <br /><br />I didn't mean locking table by sql command. I meant this atomic locking which mysql does when you write to table.<br />When you do show processlist you can watch state field for queries. If you issue a long update query and a concurrent select query on the same table you can see that select query has state "locked", because it waits for update to complete.<br />You can also watch "show status" which in version 3.23.33+ shows Table_locks_waited and Table_locks_immediate.<br />Typically when you have short queries you will have locks_waited much smaller than locks_immediate (ie. 30 waited and 60000 immediate on my system during single evening hour), which means that only few queries had to wait for other queries to complete.<br />On busy hours on my forum waited/immediated is about 1/50 (compare with above 1/2000). Also slow_queries (that is queries longer than long_query_time variable, default 10sec) is getting large (normally <10, it grows >1000)<br /><br />> I don't think there would be any way to change the scripts if <br />> tables are always locked from and insert,select,update etc. <br />> as your forums grow the amount of traffic will keep tables <br />> almost continuosly locked<br /><br />If you move b_counter to new table updates of b_counter won't be locking w3t_posts for selects.<br />New table would be smaller so updates would also run quicker.<br />I will turn off read counter for a while to see if it's the main reason of locks.<br /><br /><br />A few tips from mysql manual which I think could be helpful:<br /><br />-Try to avoid complex SELECT queries on tables that are updated a lot. This is to avoid problems with table locking<br /><br />-Get Your Data as Small as Possible<br /><br />-If you very often need to calculate things based on information from a lot of rows (like counts of things), it's probably much better to introduce a new table and update the counter in real time. An update of type UPDATE table set count=count+1 where index_column=constant is very fast! This is really important when you use databases like MySQL that only have table locking (multiple readers / single writers). <br /><br />- Use HEAP tables to get more speed when possible. (I've changed w3t_Online to heap - it doesn't help a lot, but why not, heap tables are created for this kind of tasks)<br /><br />-In some circumstances it can be beneficial to split into two a table that is scanned very often. This is especially true if it is a dynamic format table and it is possible to use a smaller static format table that can be used to find the relevant rows when scanning the table. <br /><br />Greetings, Piotr
_________________________
Greetings, Piotr
|
|
Top
|
|
|
|
 |
 |
 |
 |
|
|