Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

JoseCarlosWeb

MySql consumindo muita CPU

Recommended Posts

Olá,

Possuo alugado um servidor dedicado com 4 cores 1.6Ghz, 16Gb de RAM, 500GB HD e link de dicado de 100Mb. Nesse servidor tenho apenas um sistema em php em funcionamento, ultimamente mesmo que não haja nenhum internauta navegando o MySql está consumindo demasiadamente a CPU, já revirei na net sobre esse assunto e as dicas são sempre as mesmas, configurei o my.cnf, criei indices no banco de dados, mas até agora nada... Segue o arquivo de configuração my.cnf

 

[mysqld]

key_buffer=312M

join_buffer=16M

max_join_size=16M

thread_concurrency=4

table_cache=2048M

open_files_limit=2000

query_cache_limit=128M

query_cache_type=2

query_cache_size=128M

long_query_time=10

slow_query_log=1

key_buffer_size=256M

slow_query_log_file="/var/log/mysql-slow.log"

max_allowed_packet=256M

sort_buffer_size=256M

max_connections=500

thread_cache_size=24

read_buffer_size=8M

read_rnd_buffer_size=64M

myisam_sort_buffer_size=256M

innodb_flush_log_at_trx_commit=2

innodb_buffer_pool_size=256M

innodb_additional_mem_pool_size=60M

wait_timeout=15

thread_cache=32

max_connections=1000

 

Essa é a situação atual do servidor com 20 pessoas acessando o site:

 

Cpu(s): 29.2%us, 3.8%sy, 0.0%ni, 66.4%id, 0.5%wa, 0.0%hi, 0.1%si, 0.0%st

Mem: 16608840k total, 4851588k used, 11757252k free, 255292k buffers

Swap: 5636088k total, 0k used, 5636088k free, 4089260k cached

 

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

27451 mysql 15 0 794m 186m 6884 S 170.7 1.2 247:29.16 mysqld

20818 nobody 15 0 9852 3184 1516 S 0.7 0.0 0:00.06 httpd

22047 nobody 15 0 9852 3184 1516 S 0.7 0.0 0:00.06 httpd

7051 nobody 15 0 9852 3212 1528 S 0.3 0.0 0:00.15 httpd

19447 nobody 15 0 9852 3184 1516 S 0.3 0.0 0:00.07 httpd

20573 nobody 15 0 9852 3204 1536 S 0.3 0.0 0:00.06 httpd

20978 nobody 15 0 9852 3176 1512 S 0.3 0.0 0:00.06 httpd

22045 nobody 15 0 9852 3184 1516 S 0.3 0.0 0:00.05 httpd

 

Peço a ajuda de todos.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não há jobs configurados?

Sua base de dados tem que tamanho em MB/GB? E quantos registros?

De que se trata a sua aplicação? É uma aplicação desenvolvida por terceiros?

Usa conexões persistentes ou você quem faz o controle?

Acesse o MySQL e execute show processlist; (mostre o resultado).

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá Prog, obrigado pela resposta,

Tem um job sim, que inicialmente funcionava normal, no arquivo mysql-slow.log que criei para registrar as consultas mais lentas a chamada ao job é a mais presente:

 

# Query_time: 1.626777 Lock_time: 0.000033 Rows_sent: 1 Rows_examined: 0

SET timestamp=1357754847;

call cron_tempo();

# Time: 130109 16:07:28

# User@Host: lance_adm[lance_adm] @ localhost []

# Query_time: 1.653683 Lock_time: 0.000035 Rows_sent: 1 Rows_examined: 0

SET timestamp=1357754848;

call cron_tempo();

# Time: 130109 16:07:29

# User@Host: lance_adm[lance_adm] @ localhost []

# Query_time: 1.561667 Lock_time: 0.000040 Rows_sent: 1 Rows_examined: 0

SET timestamp=1357754849;

call cron_tempo();

 

OBS: Existem mais umas 500 linha como essas

 

Trata-se de um leilão de centavos

Não sei se tem a ver com a conexão persistente ou não, porque

nesse momento, sem nenhum usuario online o mysql está consumindo 90%. Mas não existe conexões persistentes no código.

 

Esse é o resultado do SHOW FULL PROCESSLIST;

 

mysql> show full processlist;

+---------+-----------+-----------+-----------+----------------+------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

| Id | User | Host | db | Command | Time | State | Info |

+---------+-----------+-----------+-----------+----------------+------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

| 2595914 | DELAYED | localhost | eximstats | Delayed insert | 230 | Waiting for INSERT | |

| 2602572 | DELAYED | localhost | eximstats | Delayed insert | 146 | Waiting for INSERT | |

| 2602573 | DELAYED | localhost | eximstats | Delayed insert | 146 | Waiting for INSERT | |

| 2611233 | root | localhost | NULL | Query | 0 | NULL | show full processlist |

| 2612849 | lance_adm | localhost | lance_bd | Sleep | 0 | | NULL |

| 2612851 | lance | localhost | lance_bd | Query | 0 | Copying to tmp table | CREATE TEMPORARY TABLE t_robos

SELECT auctionID, productID, auc_due_time, auc_plus_time, auc_due_price+auc_plus_price AS prox_valor, proximo_robo(ultUserId) AS prox_robo

from c_cron_tempo where auc_due_time < 2 |

+---------+-----------+-----------+-----------+----------------+------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

6 rows in set (0.00 sec)

 

 

O código do JOB é esse:

BEGIN


 DECLARE total BIGINT DEFAULT 0;
 DECLARE bloquear TINYINT(1) DEFAULT 0;
 DECLARE qt_robo INT DEFAULT 0;

 SELECT COUNT(*) FROM cron INTO total;
 IF total = 0 THEN
   INSERT INTO cron (tempo) VALUES (NOW());
   SELECT 1, 0 INTO total, bloquear;

 ELSE
   SELECT NOW()-tempo AS total, bloquear FROM cron INTO total, bloquear;

 END IF;

 IF total > 0 AND bloquear = 0 THEN
   UPDATE cron SET tempo=NOW();

   BEGIN

-- contagem regressiva dos leiloes ativos
   update auc_due_table adt left join auction a on a.auctionID=adt.auction_id
            set adt.auc_due_time=adt.auc_due_time-1
            where adt.auc_due_time>0 and a.pause_status=0 and a.auc_status=2;

-- ativar os leiloes futuros que estao no horario de inicio
   update auction a set auc_status=2 where pause_status=0 and auc_status=1 and
            (TIMEDIFF(DATE_FORMAT(concat(concat(auc_start_date,' '),
            auc_start_time),'%Y-%m-%d %T'),DATE_FORMAT(NOW(),'%Y-%m-%d %T'))+0)<0;
-- :: deve criar auc_due_table se nao existir
   Insert Into auc_due_table(auction_id,auc_due_time,auc_due_price,auc_limite_total)
            SELECT a.auctionID,m.auc_plus_time,m.auc_plus_price,a.max_robot_consec
               FROM auction a inner join auction_management m on
               a.time_duration=m.auc_manage left join auc_due_table t on a.auctionID=t.auction_id
               where t.auc_due_time is null and (a.auc_status=2 or a.auc_status=1) and a.pause_status=0;

-- robo mantendo o preco minimo se exiter mais de 1 robo cadastrado

   SELECT COUNT(*) AS tot FROM registration where admin_user_flag='1' and user_delete_flag != 'd' INTO qt_robo;
   IF qt_robo > 1 THEN

     CREATE TEMPORARY TABLE t_robos
     SELECT auctionID, productID, auc_due_time, auc_plus_time, auc_due_price+auc_plus_price AS prox_valor, proximo_robo(ultUserId) AS prox_robo
             from c_cron_tempo where auc_due_time < 2;
-- dar lance
     Insert into bid_account (user_id,bidpack_buy_date,bid_count,auction_id,product_id,bid_flag,bidding_price,bidding_type,bidding_time)
             SELECT prox_robo,NOW(),'1',auctionID,productID,'d',prox_valor,'s',auc_due_time FROM t_robos;

-- retornar o tempo e aumentar o preco
     UPDATE auc_due_table INNER JOIN t_robos SET auc_limite_atual=auc_limite_atual+1, auc_due_table.auc_due_time=t_robos.auc_plus_time, auc_due_table.auc_due_price=t_robos.prox_valor
             WHERE auc_due_table.auction_id = t_robos.auctionID;

     DROP TABLE t_robos;


-- listar os leiloes em aberto que nao possuem lance
     CREATE TEMPORARY TABLE t_robos
     SELECT a.auctionID, a.productID, t.auc_due_time, m.auc_plus_time, t.auc_due_price+m.auc_plus_price AS prox_valor, m.auc_plus_price, proximo_robo(0) as prox_robo
               FROM auction a inner join auction_management m on a.time_duration=m.auc_manage left join auc_due_table t on a.auctionID=t.auction_id
               left join bid_account l on a.auctionID = l.auction_id
               where a.auc_status=2 and a.pause_status=0 and l.auction_id is null and t.auc_due_time < 3;

-- dar lance
     Insert into bid_account (user_id,bidpack_buy_date,bid_count,auction_id,product_id,bid_flag,bidding_price,bidding_type,bidding_time)
             SELECT prox_robo,NOW(),'1',auctionID,productID,'d',prox_valor,'s',auc_due_time FROM t_robos;

-- retornar o tempo e aumentar o preco
     UPDATE auc_due_table INNER JOIN t_robos SET auc_due_table.auc_due_time=t_robos.auc_plus_time, auc_due_table.auc_due_price=t_robos.prox_valor
             WHERE auc_due_table.auction_id = t_robos.auctionID;

     DROP TABLE t_robos;
   END IF;

-- fechar os leiloes q esgotaram o tempo :: avisar ganhador
  update auc_due_table adt left join auction a on a.auctionID=adt.auction_id left join
          (select g.auction_id, d.user_id from
              (select max(id) as id, auction_id from bid_account
                           where bid_flag = 'd' and bidding_type = 's'
                           group by auction_id) g inner join
                       bid_account d on g.id=d.id) b on a.auctionID=b.auction_id
                   set a.auc_status=3, a.auc_final_price = adt.auc_due_price,
                       a.auc_final_end_date=NOW(), a.buy_user = COALESCE(b.user_id,0)
                   where adt.auc_due_time=0 and a.pause_status=0 and a.auc_status=2;

-- cadastrar a opcao de pagamento dos leiloes q venceram
   Insert into won_auctions (auction_id,userid,won_date)
       Select a.auctionID,buy_user,NOW() from auction a left join
           won_auctions w on a.auctionID=w.auction_id
       where w.auction_id is null and auc_status=3 and situacao = 0;

   COMMIT;
   END;
   SELECT true AS resultado;

 ELSE
   SELECT false AS resultado;
 END IF;

END

 

Só complementando, instalei uma ferramenta chamada mytop. Ela sempre me retorna algo parecido com isso:

 

Queries: 150.0 qps: 0 Slow: 0.0 Se/In/Up/De(%): 00/00/00/00

qps now: 0 Slow qps: 0.0 Threads: 3 ( 2/ 29) 00/00/00/00

Key Efficiency: 100.0% Bps in/out: 0.1/ 15.6 Now in/out: 8.4/ 1.8k

 

Id User Host/IP DB Time Cmd Query or State

-- ---- ------- -- ---- --- ----------

2686119 root localhost 0 Query show full processlist

2713290 lance_adm localhost lance_bd 0 Sleep

2713291 lance localhost lance_bd 0 Query CREATE TEMPORARY TABLE t_robos SELECT auctionID, productID, auc_due_time, auc_plus_time, auc_due_price+au

2713319 lance_adm localhost lance_bd 0 Sleep

2710573 DELAYED localhost eximstats 40 Delaye Waiting for INSERT

Compartilhar este post


Link para o post
Compartilhar em outros sites

Esse JOB roda a cada segundo? Como o sistema fica com o JOB desligado?

 

Achei o JOB com muita coisa, não que isto não seja necessário, mas me parece que ele precisa ser otimizado e ver se alguns desses processamentos não podem ser substituídos por outros processos fora do banco de dados.

 

Quanto ao resultado do mytop, é justamente uma das atividades que ocorre dentro do JOB, neste caso, a criação de uma tabela temporária baseada no SELECT abaixo:

SELECT a.auctionID, a.productID, t.auc_due_time, m.auc_plus_time, t.auc_due_price+m.auc_plus_price AS prox_valor, m.auc_plus_price, proximo_robo(0) as prox_robo
               FROM auction a inner join auction_management m on a.time_duration=m.auc_manage left join auc_due_table t on a.auctionID=t.auction_id
               left join bid_account l on a.auctionID = l.auction_id
               where a.auc_status=2 and a.pause_status=0 and l.auction_id is null and t.auc_due_time < 3;

 

No inicio você disse que o JOB funcionava bem, porém, conforme o banco de dados vai crescendo, algumas consultas que eram velozes no inicio, quando haviam poucos dados, ficaram mais lentas...

 

Algumas opções:

- rever algumas regras de negócio e processamentos;

- criar mais alguns indices;

- fazer um backup dos dados antigos, removendo-os da base atual sem prejudicar o funcionamento do sistema; ou

- criar tabelas apenas para base histórica (consulta), enquanto as tabelas de negócio para o funcionamento do sistema ficam com poucos dados;

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá meu caro,

Cê me acredita que ainda estou sofrendo com esse server?

eu apaguei a aplicação e o banco de dados e acredite... o mysql continua consumindo muita CPU sozinho.

Ou seja, não era só a aplicação, ainda existe algo, mas o que?

Vocês poderiam me da uma direção do que pode ser esse gargalo?

 

Agradeço a ajuda.

Compartilhar este post


Link para o post
Compartilhar em outros sites

O show processlist; do mysql ainda mostra que esta executando alguma coisa?

Tente reiniciar o serviço do banco de dados, geralmente service mysqld restart (depende da distribuição) da conta do recado.

 

Estava reavaliando seu arquivo de configuração:

 

[mysqld]
key_buffer=312M
join_buffer=16M
max_join_size=16M
thread_concurrency=4
table_cache=2048M
open_files_limit=2000
query_cache_limit=128M
query_cache_type=2
query_cache_size=128M
long_query_time=10
slow_query_log=1
key_buffer_size=256M
slow_query_log_file="/var/log/mysql-slow.log"
max_allowed_packet=256M
sort_buffer_size=256M
max_connections=500
thread_cache_size=24
read_buffer_size=8M
read_rnd_buffer_size=64M
myisam_sort_buffer_size=256M
innodb_flush_log_at_trx_commit=2
innodb_buffer_pool_size=256M
innodb_additional_mem_pool_size=60M
wait_timeout=15
thread_cache=32
max_connections=1000

 

 

Percebi que algumas chaves estão repetidas, você alterou este arquivo na tentativa de melhorar o problema? Alguns valores me parecem excessivamente altos, usou algum tutorial como referência?

 

Aguardamos retorno.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.