Possibilité de mettre en œuvre la journalisation avec un seul fsync par engagement?

StackOverflow https://stackoverflow.com/questions/3800108

  •  25-09-2019
  •  | 
  •  

Question

Disons que vous construisez un journaling / système de stockage WAL-logging. Pouvez-vous mettre en œuvre simplement par ce (pour chaque transaction) annexant les données (avec write (2)), annexant un marqueur commettras, puis fsync-ing?

Le scénario à considérer est si vous faites un grand nombre d'écritures dans ce journal puis fsync, et il y a un échec pendant la fsync . Sont les inodes pointeurs de bloc direct / indirect vidées seulement après que tous les blocs de données sont vidées, ou y at-il aucune garantie que les blocs sont vidées dans l'ordre? Dans ce dernier cas, puis lors de la récupération, si vous voyez un commettras marqueur à la fin du fichier, vous ne pouvez pas faire confiance que les données entre elle et le marqueur validation précédente est significative. Ainsi, vous devez compter sur un autre mécanisme (impliquant au moins une autre fsync) pour déterminer dans quelle mesure du fichier journal est compatible (par exemple, l'écriture / fsyncing les données, en train d'écrire / fsyncing le marqueur commettras).

Si cela fait une différence, se demandant surtout de ext3 / ext4 comme le contexte.

Était-ce utile?

La solution

Notez que de Linux et de fsync de mac os et fdatasync sont incorrects par défaut. Windows est correcte par défaut, mais peut émuler linux à des fins d'analyse comparative.

En outre, les problèmes fdatasync multidisques écrit si vous ajoutez à la fin d'un fichier, car il a besoin de mettre à jour le fichier inode avec la nouvelle longueur. Si vous voulez avoir une écriture par engagement, votre meilleur pari est de pré-allouer de l'espace journal, stocker un CRC des entrées de journal dans le marqueur commit, et d'émettre un seul fdatasync () à commettre. De cette façon, peu importe à quel point le système d'exploitation / matériel Réorganiser derrière votre dos, vous pouvez trouver un préfixe du journal qui a frappé en fait le disque.

Si vous voulez utiliser le journal pour commits durable ou écrire en avance, les choses deviennent plus difficiles, puisque vous devez vous assurer que fsync fonctionne réellement. Sous Linux, vous souhaitez désactiver le cache d'écriture sur disque avec hdparm, ou monter la partition avec barrière définie sur true. [Edit: Je reconnais mon erreur, barrière ne semble pas donner la sémantique correcte. SATA et SCSI introduisent un certain nombre de primitives, comme les barrières d'écriture et de mise en file des commandes natives qui permettent des systèmes d'exploitation pour exporter des primitives qui permettent l'enregistrement WAL. D'après ce que je peux dire à partir des pages de manuel et en ligne, Linux expose que ces systèmes de fichiers pour les développeurs, et non pas vers l'espace utilisateur.]

Paradoxalement, la désactivation du cache d'écriture sur disque conduit parfois à une meilleure performance, puisque vous obtenez plus de contrôle sur la planification d'écriture dans l'espace utilisateur; si le disque fait la queue un tas de requêtes d'écriture synchrone, vous finissez par exposer les pics de latence étranges à l'application. La désactivation de cache d'écriture empêche que cela se produise.

Enfin, les systèmes réels utilisent le groupe engagent, et faire <1 écriture de synchronisation par commit avec des charges de travail simultanées.

Autres conseils

Il n'y a aucune garantie sur l'ordre dans lequel les blocs sont vidées sur le disque. Ces jours-ci, même le lecteur lui-même peut re-commander des blocs sur leur chemin vers les plateaux.

Si vous voulez appliquer la commande, vous devez au moins fdatasync() entre les écritures que vous voulez commandés. Toutes les promesses de synchronisation est que quand il retourne , tout écrit avant la synchronisation a frappé le stockage.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top