Injecter un site existant dans Spip et optimiser Spip pour un gros site

[Je croyais l'avoir déjà envoyé mais je ne vois rien dans la liste. Je
réenvoie, amélioré.]

Je suis en train d'étudier la possibilité de faire passer un gros site
existant (plein de pages HTML déjà faites) dans Spip *et* de gérer un
(très) gros site Spip.

Le contexte : un client (les clients ont toujours raison) a un site de
180 000 pages HTML statiques qu'il voudrait passer dans Spip pour
bénéficier des forums par rubrique, des mots-clés, etc.

Premier problème : l'injecter dans Spip. En m'aidant de
<URL:http://www.uzine.net/article713.html&gt;, je fais un programme qui
extrait le titre et le contenu de chaque page et l'envoit dans la
base. Ca prend deux heures, mais ça marche, j'ai mis 110 000 articles
dans Spip.

Questions sur le premier problème : y a t-il des pièges ou bien des
risques particuliers ? Le schéma de la base de données de Spip ne
contient pas de contraintes d'intégrité (parce que MySQL ne sait pas
faire ?). Par exemple, on peut injecter un article avec un statut nul
alors que Spip ne sait pas les traiter. C'est par essai/erreur que
j'ai découvert les contraintes à respecter.

Deuxième problème : une fois tout injecté, ça rame. Horriblement. Bien
sûr, la machine de test est peu rapide mais je suis pour l'instant le
seul lecteur. Donc, faut optimiser.

<URL:http://www.uzine.net/article997.html&gt; et la page ci-dessus ne
contiennent guère d'indication pour ce problème des gros
sites. Notamment, rien sur l'optimisation de la base de données, les
index recommandés, etc. Un profilage sommaire indique que c'est MySQL
qui nous bloque. Je lis
<URL:http://www.mysql.com/doc/M/y/MySQL_Optimisation.html&gt;, je vais
faire quelques EXPLAIN mais, avant de me lancer, je voudrais savoir qi
quelqu'un l'a déjà fait et écrit le "SPIP Optimisation HOWTO" ?

Question supplémentaire sur le deuxième problème : j'injecte tout dans
une seule rubrique. Ai-je intérêt, pour ce qui concerne les
performances, à injecter dans N rubriques ? Ca ne changera pas la
table spip_articles mais cela peut changer la façon dont Spip accès
aux articles.

From antoine@rezo.net Wed Mar 6 12:58:16 2002

Return-Path: <antoine@rezo.net>
Received: from rezo.net (localhost [127.0.0.1])
  by miel.brainstorm.fr (Postfix) with SMTP id 115FE1D377
  for <spip@rezo.net>; Wed, 6 Mar 2002 12:58:16 +0100 (CET)
Received: from 193.49.124.64
        (SquirrelMail authenticated user antoine)
        by rezo.net with HTTP;
        Wed, 6 Mar 2002 12:58:16 +0100 (CET)
Message-ID: <60265.193.49.124.64.1015415896.squirrel@rezo.net>
Date: Wed, 6 Mar 2002 12:58:16 +0100 (CET)
Subject: Re: [Spip] Injecter un site existant dans Spip et optimiser Spip
  pour un
From: "Antoine" <antoine@rezo.net>
To: <spip@rezo.net>
In-Reply-To: <20020306113649.GA5424@staff.netaktiv.com>
References: <20020306113649.GA5424@staff.netaktiv.com>
X-Priority: 3
Importance: Normal
X-MSMail-Priority: Normal
X-Mailer: SquirrelMail (version 1.2.2)
MIME-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
Sender: spip-bounces@rezo.net
Errors-To: spip-bounces@rezo.net
X-BeenThere: spip@rezo.net
X-Mailman-Version: 2.1a4+
Precedence: bulk
List-Help: <mailto:spip-request@rezo.net?subject=help>
List-Post: <mailto:spip@rezo.net>
List-Subscribe: <http://listes.rezo.net/mailman/listinfo/spip&gt;,
  <mailto:spip-request@rezo.net?subject=subscribe>
List-Id: SPIP : questions/reponses <spip.rezo.net>
List-Unsubscribe: <http://listes.rezo.net/mailman/listinfo/spip&gt;,
  <mailto:spip-request@rezo.net?subject=unsubscribe>
List-Archive: Discuter chez rezo.net
X-List-Received-Date: Wed, 06 Mar 2002 11:58:16 -0000
Status: O
Content-Length: 2232
Lines: 56

Salut,

Premier problème : l'injecter dans Spip. En m'aidant de
<URL:http://www.uzine.net/article713.html&gt;, je fais un programme qui
extrait le titre et le contenu de chaque page et l'envoit dans la
base. Ca prend deux heures, mais ça marche, j'ai mis 110 000 articles
dans Spip.

Effectivement, c'est assez gros. Tu dois être le premier à faire un
SPIP de cette taille (même le Diplo fait pâle figure à côté, avec ses
quelques milliers d'articles). Chapeau :slight_smile:

C'est par essai/erreur que j'ai
découvert les contraintes à respecter.

Il n'y en a pas beaucoup, surtout pour les articles. Tu devrais faire
un tour dans ecrire/optimiser.php3, qui s'occupe périodiquement de
forcer certaines règles de cohérence et de propreté dans la base.

(au fait, oui, MySQL ne connaît pas les contraintes, par contre c'est
vrai que pour les statuts on aurait pu mettre un ENUM...)

Deuxième problème : une fois tout injecté, ça rame. Horriblement. Bien
sûr, la machine de test est peu rapide mais je suis pour l'instant le
seul lecteur. Donc, faut optimiser.

Quelles sont les pages qui rament ? Dans l'espace public et/ou dans
l'espace privé ?

Question supplémentaire sur le deuxième problème : j'injecte tout dans
une seule rubrique. Ai-je intérêt, pour ce qui concerne les
performances, à injecter dans N rubriques ? Ca ne changera pas la
table spip_articles mais cela peut changer la façon dont Spip accès aux
articles.

Ah oui, c'est clair que ce sera plus rapide, surtout dans l'espace privé
("naviguer dans le site" et "afficher tout le site"). Pour que ça se
répercute dans l'espace public, il faut bien sûr que celui-ci utilise
la discrimination par rubriques dans l'affichage.

Dans ton cas, il peut aussi être utile d'ajouter un index sur le statut
et sur la date des articles (notamment si tu veux afficher la liste des
derniers articles publiés). En tout état de cause, il serait bon d'activer
le "slow_query_log" dans MySQL et de faire un EXPLAIN des requêtes trop
longues.

Une fois assuré que toutes les requêtes font appel à un index, tu devras
peut-être optimiser MySQL lui-même (en augmentant le key_buffer_size si
nécessaire). Tu nous tiens au courant de tes avancées ?

Amicalement

Antoine.

@ Stephane Bortzmeyer <bortzmeyer@netaktiv.com> :

Premier problème : l'injecter dans Spip. En m'aidant de
<URL:http://www.uzine.net/article713.html&gt;, je fais un programme qui
extrait le titre et le contenu de chaque page et l'envoit dans la
base. Ca prend deux heures, mais ça marche, j'ai mis 110 000 articles
dans Spip.

tu as mis la date aussi ?

Deuxième problème : une fois tout injecté, ça rame. Horriblement.

qu'est-ce qui rame ? L'affichage via php ou les requêtes "a la mano" sur la
base ?

sûr, la machine de test est peu rapide mais je suis pour l'instant le
seul lecteur. Donc, faut optimiser.

a priori un ou plusieurs lecteurs ça ne pose pas de problème, car la plupart
des lecteurs se voient retourner des pages cachées (donc presque
"statiques", en tous cas sans aucun accès aux données, ni même connexion à
la base si tu as déselectionné le calcul des statistiques du site).

<URL:http://www.uzine.net/article997.html&gt; et la page ci-dessus ne
contiennent guère d'indication pour ce problème des gros
sites. Notamment, rien sur l'optimisation de la base de données, les
index recommandés, etc. Un profilage sommaire indique que c'est MySQL
qui nous bloque.

Ta base et ton expérience seront précieuses pour ça. Pour le Diplo, on a
ajouté quelques indexes, mais je ne me souviens pas précisément lesquels.
Comment fait-on pour "dumper" la structure ??

Je lis <URL:http://www.mysql.com/doc/M/y/MySQL_Optimisation.html&gt;, je vais
faire quelques EXPLAIN mais, avant de me lancer, je voudrais savoir qi
quelqu'un l'a déjà fait et écrit le "SPIP Optimisation HOWTO" ?

Non, guère.

Question supplémentaire sur le deuxième problème : j'injecte tout dans
une seule rubrique. Ai-je intérêt, pour ce qui concerne les
performances, à injecter dans N rubriques ? Ca ne changera pas la
table spip_articles mais cela peut changer la façon dont Spip accès
aux articles.

Oui, tu y as intérêt, ne serait-ce que pour que l'espace privé soit gérable.
Rubrique tes choses ainsi :

Archives-
         1998-
              1998-01-
                      1998-01-01
                      1998-01-02
                      ...
              1998-02-
              ...

         1999-
         ...

Divers-
        Abonnements
        ...

Forums-
        Pour ou contre la dictature du prolétariat ?
        Faut-il manger des nouilles ?

etc.

-- Fil

On Wed, Mar 06, 2002 at 12:58:16PM +0100,
Antoine <antoine@rezo.net> wrote
a message of 61 lines which said:

(au fait, oui, MySQL ne connaît pas les contraintes,

Ce n'est pas tout à fait exact. MySQL est une daube mais il y a au
moins NOT NULL (qui est vérifié). Mais Spip ne l'utilise pas de
manière cohérente, il y a un NOT NULL sur id_parent dans
spip_rubriques mais pas sur statut dans spip_articles.

Quelles sont les pages qui rament ? Dans l'espace public et/ou dans
l'espace privé ?

La page d'accueil par défaut (dans l'espace privé, ça va mieux). Elle
fait une requête inoptimisable puisqu'elle porte sur *tous* les
articles, quelle que soit leur rubrique :

SELECT articles.id_article,articles.id_rubrique,articles.id_secteur,articles.surtitre,articles.titre,articles.soustitre,articles.date,articles.date_redac,articles.visites,articles.statut,articles.accepter_forum,articles.texte,articles.chapo FROM spip_articles AS articles WHERE articles.statut='publie' ORDER BY articles.date DESC ;

répercute dans l'espace public, il faut bien sûr que celui-ci utilise
la discrimination par rubriques dans l'affichage.

OK, TODO.

Dans ton cas, il peut aussi être utile d'ajouter un index sur le
statut

Fait. Il est dans les possible_keys du EXPLAIN mais pas dans les keys
sans doute (un expert MySQL peut confirmer ?) parce que tous les
articles ont le statut "publié".

et sur la date des articles (notamment si tu veux afficher la liste

Fait aussi mais MySQL semble l'ignorer.

derniers articles publiés). En tout état de cause, il serait bon d'activer
le "slow_query_log" dans MySQL et de faire un EXPLAIN des requêtes trop
longues.

Oui, c'est toujours la bonne approche avec un SGBD mais, malgré mes
index, yveupa (on ne voit pas l'index articles_date qui serait
pourtant utile pour le tri par date) :

mysql> explain SELECT articles.id_article,articles.id_rubrique,articles.id_secteur,articles.surtitre,articles.titre,articles.soustitre,articles.date,articles.date_redac,articles.visites,articles.statut,articles.accepter_forum,articles.texte,articles.chapo FROM spip_articles AS articles WHERE articles.statut='publie' ORDER BY articles.date DESC ;
+----------+------+-----------------+------+---------+------+--------+----------------------------+
| table | type | possible_keys | key | key_len | ref | rows | Extra |
+----------+------+-----------------+------+---------+------+--------+----------------------------+
| articles | ALL | articles_statut | NULL | NULL | NULL | 114595 | where used; Using filesort |
+----------+------+-----------------+------+---------+------+--------+----------------------------+
1 row in set (0.10 sec)

On Wed, Mar 06, 2002 at 08:49:30PM +0100,
Fil <fil@rezo.net> wrote
a message of 71 lines which said:

> base. Ca prend deux heures, mais ça marche, j'ai mis 110 000 articles
> dans Spip.

tu as mis la date aussi ?

Oui, prise dans la date du fichier HTML.

> Deuxième problème : une fois tout injecté, ça rame. Horriblement.

qu'est-ce qui rame ? L'affichage via php ou les requêtes "a la mano" sur la
base ?

Les deux pareil.

a priori un ou plusieurs lecteurs ça ne pose pas de problème, car la plupart
des lecteurs se voient retourner des pages cachées (donc presque
"statiques", en tous cas sans aucun accès aux données,

Oui, mais encore faut-il réussir à la calculer une fois. Et c'est là
que ça timeoute à tout va.

Ta base et ton expérience seront précieuses pour ça. Pour le Diplo, on a
ajouté quelques indexes, mais je ne me souviens pas précisément lesquels.
Comment fait-on pour "dumper" la structure ??

DESCRIBE spip_articles; (la colonne KEY)

Sinon, les CREATE INDEX doivent être dans le dump généré par
mysqldump.

        Pour ou contre la dictature du prolétariat ?

Pour, évidemment.

From dominique.javet@bni.ch Thu Mar 7 17:28:34 2002

Return-Path: <dominique.javet@bni.ch>
Received: from mta1n.bluewin.ch (mta1n.bluewin.ch [195.186.1.210])
  by miel.brainstorm.fr (Postfix) with ESMTP id 908141D494
  for <spip@rezo.net>; Thu, 7 Mar 2002 17:28:34 +0100 (CET)
Received: from djavet.bni.ch (195.186.174.28) by mta1n.bluewin.ch (Bluewin AG
  6.0.040)
        id 3C83392700178E5A for spip@rezo.net; Thu, 7 Mar 2002
  17:28:34 +0100
Message-Id: <5.1.0.14.2.20020307172803.02c21e00@pop3.norton.antivirus>
X-Sender: dominique.javet/mail.bni.ch@pop3.norton.antivirus
X-Mailer: QUALCOMM Windows Eudora Version 5.1
Date: Thu, 07 Mar 2002 17:33:41 +0100
To: spip@rezo.net
From: Dominique Javet <dominique.javet@bni.ch>
Mime-Version: 1.0
Content-Type: text/plain; charset="iso-8859-1"; format=flowed
Content-Transfer-Encoding: quoted-printable
Subject: [Spip] Install SPIP avec un ancienne base MySQL
Sender: spip-bounces@rezo.net
Errors-To: spip-bounces@rezo.net
X-BeenThere: spip@rezo.net
X-Mailman-Version: 2.1a4+
Precedence: bulk
List-Help: <mailto:spip-request@rezo.net?subject=help>
List-Post: <mailto:spip@rezo.net>
List-Subscribe: <http://listes.rezo.net/mailman/listinfo/spip&gt;,
  <mailto:spip-request@rezo.net?subject=subscribe>
List-Id: SPIP : questions/reponses <spip.rezo.net>
List-Unsubscribe: <http://listes.rezo.net/mailman/listinfo/spip&gt;,
  <mailto:spip-request@rezo.net?subject=unsubscribe>
List-Archive: Discuter chez rezo.net
X-List-Received-Date: Thu, 07 Mar 2002 16:28:34 -0000
Status: O
Content-Length: 500
Lines: 26

Hello,

Si j'installe SPIP avec l'installer php dans un nouveau r=E9pertoire et que=
=20
je fais la connection avec une base MySQL existante, est-ce que SPIP va=20
=E9craser les tables existantes ou bien les reconna=EEtre et les r=E9utilise=
r?

A+;D om

::::::::::::::::::::::::::::::::::::::::::::
B N I
Business Network Integration

rte de Chantemerle 58
CH-1763 Granges-Paccot

Tel +41 (0)26 465 14 33
Fax +41 (0)26 465 14 34

web: http://www.bni.ch
email: dominique.javet@bni.ch

Dans ton cas, il peut aussi être utile d'ajouter un index sur le
statut

Fait. Il est dans les possible_keys du EXPLAIN mais pas dans les keys
sans doute (un expert MySQL peut confirmer ?) parce que tous les
articles ont le statut "publié".

Je voulais dire un index multi-colonnes sur statut et date :
ALTER TABLE spip_articles ADD INDEX statut_date (statut, date)

Cela devrait permettre d'utiliser l'index pour le tri après avoir
sélectionné par statut (à vérifier !).

On Thu, Mar 07, 2002 at 05:30:42PM +0100,
Antoine <antoine@rezo.net> wrote
a message of 21 lines which said:

Je voulais dire un index multi-colonnes sur statut et date :
ALTER TABLE spip_articles ADD INDEX statut_date (statut, date)

Cela devrait permettre d'utiliser l'index pour le tri après avoir
sélectionné par statut (à vérifier !).

Ce n'est pas comme cela que je comprends la doc :

http://www.mysql.com/doc/C/R/CREATE_INDEX.html

A column list of the form (col1,col2,...) creates a multiple-column
index. Index values are formed by concatenating the values of the
given columns.

Bon, à tout hasard, j'ai essayé et, bien que le nouvel index
apparaisse dans possible_keys, il n'est toujours pas dans keys.

From fil@miel.brainstorm.fr Thu Mar 7 17:44:01 2002

Return-Path: <fil@miel.brainstorm.fr>
Received: by miel.brainstorm.fr (Postfix, from userid 1001)
  id A261B1D3F7; Thu, 7 Mar 2002 17:44:01 +0100 (CET)
Date: Thu, 7 Mar 2002 17:44:01 +0100
From: Fil <fil@rezo.net>
To: spip <spip@rezo.net>
Subject: Re: [Spip] Injecter un site existant dans Spip et optimiser Spip
  pour un gros site
Message-ID: <20020307164401.GC26318@rezo.net>
Mail-Followup-To: spip <spip@rezo.net>
References: <20020306113649.GA5424@staff.netaktiv.com>
  <20020306194930.GA31665@rezo.net> <20020307162317.GC22850@staff.netaktiv.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
In-Reply-To: <20020307162317.GC22850@staff.netaktiv.com>
User-Agent: Mutt/1.3.27i
Sender: spip-bounces@rezo.net
Errors-To: spip-bounces@rezo.net
X-BeenThere: spip@rezo.net
X-Mailman-Version: 2.1a4+
Precedence: bulk
List-Help: <mailto:spip-request@rezo.net?subject=help>
List-Post: <mailto:spip@rezo.net>
List-Subscribe: <http://listes.rezo.net/mailman/listinfo/spip&gt;,
  <mailto:spip-request@rezo.net?subject=subscribe>
List-Id: SPIP : questions/reponses <spip.rezo.net>
List-Unsubscribe: <http://listes.rezo.net/mailman/listinfo/spip&gt;,
  <mailto:spip-request@rezo.net?subject=unsubscribe>
List-Archive: Discuter chez rezo.net
X-List-Received-Date: Thu, 07 Mar 2002 16:44:01 -0000
Status: O
Content-Length: 3313
Lines: 79

@ Stephane Bortzmeyer <bortzmeyer@netaktiv.com> :

> qu'est-ce qui rame ? L'affichage via php ou les requêtes "a la mano" sur la
> base ?
Les deux pareil.

Donc c'est la base.

Oui, mais encore faut-il réussir à la calculer une fois. Et c'est là
que ça timeoute à tout va.

Tu pourrais aussi écrire un squelette moins brutal pour ta page d'accueil !
Que veux-tu afficher sur cette page ?

> Comment fait-on pour "dumper" la structure ??
DESCRIBE spip_articles; (la colonne KEY)

mysql> DESCRIBE spip_articles;
+----------------+---------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+---------------+------+-----+---------------------+----------------+
| id_article | bigint(21) | | PRI | NULL | auto_increment |
| surtitre | text | | | |
| titre | text | | | |
| soustitre | text | | | |
| id_rubrique | bigint(21) | | MUL | 0 |
| descriptif | text | | MUL | |
| chapo | mediumtext | | | |
| texte | longblob | | | |
| ps | mediumtext | | | |
| date | datetime | | | 0000-00-00 00:00:00 |
| statut | varchar(10) | | MUL | 0 |
| id_secteur | bigint(21) | | | 0 |
| maj | timestamp(14) | YES | | NULL |
| export | varchar(10) | YES | | oui |
| date_redac | datetime | | | 0000-00-00 00:00:00 |
| visites | int(11) | | | 0 |
| referers | blob | | | |
| accepter_forum | char(3) | YES | | NULL |
+----------------+---------------+------+-----+---------------------+----------------+

Sinon, les CREATE INDEX doivent être dans le dump généré par
mysqldump.

-- Server version 3.23.49
--
-- Table structure for table 'spip_articles'
--
DROP TABLE IF EXISTS spip_articles;
CREATE TABLE spip_articles (
  id_article bigint(21) NOT NULL auto_increment,
  surtitre text NOT NULL,
  titre text NOT NULL,
  soustitre text NOT NULL,
  id_rubrique bigint(21) NOT NULL default '0',
  descriptif text NOT NULL,
  chapo mediumtext NOT NULL,
  texte longblob NOT NULL,
  ps mediumtext NOT NULL,
  date datetime NOT NULL default '0000-00-00 00:00:00',
  statut varchar(10) NOT NULL default '0',
  id_secteur bigint(21) NOT NULL default '0',
  maj timestamp(14) NOT NULL,
  export varchar(10) default 'oui',
  date_redac datetime NOT NULL default '0000-00-00 00:00:00',
  visites int(11) NOT NULL default '0',
  referers blob NOT NULL,
  accepter_forum char(3) default NULL,
  PRIMARY KEY (id_article),
  KEY id_rubrique (id_rubrique),
  KEY descriptif (descriptif(10)),
  KEY statut (statut(2))
) TYPE=MyISAM PACK_KEYS=1;

> Pour ou contre la dictature du prolétariat ?
Pour, évidemment.

Tant qu'on nous enlève pas la confiture !

-- Fil

Je viens d'installer Spip (1.3.1) chez un nouvel hébergeur. Tout ce passe
bien,
install, essai d'écriture d'un article, réferencement auto, petition...
jusqu'à ce que je vide le cache dans le menu configuration de spip.

j'obtiens alors les 3 messages suivants :

Warning: opendir() has been disabled for security reasons in
/home/www_xyz/monsite/inc-cache.php on line 10

Warning: readdir() has been disabled for security reasons in
/home/www_xyz/monsite/inc-cache.php on line 12

Warning: closedir() has been disabled for security reasons in
/home/www_xyz/monsite/inc-cache.php on line 28

Dois-je en déduire que l'utilisation de Spip sur ce serveur est impossible ?

merci de votre aide